From f137b6530b5b6cff7604001bfae1e56531cc47f6 Mon Sep 17 00:00:00 2001 From: Samuel Marks <807580+SamuelMarks@users.noreply.github.com> Date: Mon, 8 Nov 2021 14:07:32 -0500 Subject: [PATCH 1/2] CMake init; [*.c] C89 support; [*.c] Use (more) correct types --- .gitignore | 3 + CMakeLists.txt | 98 ++++++++++ cmake/BundleIcon.icns | Bin 0 -> 33452 bytes cmake/CTestConfig.cmake | 7 + cmake/Config.cmake.in | 4 + cmake/CustomVolumeIcon.icns | Bin 0 -> 37827 bytes cmake/Info.plist | 14 ++ cmake/MultiCPackConfig.cmake | 6 + cmake/README.txt | 1 + cmake/Welcome.txt | 3 + cmake/config.h.in | 9 + demo/CMakeLists.txt | 35 ++++ demo/demo_dir.c | 3 +- demo/demo_pak.c | 6 +- demo/demo_tar.c | 3 +- demo/demo_zip.c | 6 +- src/CMakeLists.txt | 51 ++++++ src/dir.c | 76 +++++--- src/pak.c | 72 +++++--- src/tar.c | 21 ++- src/vfs.c | 9 +- src/zip.c | 199 +++++++++++--------- stdarc.c | 345 +++++++++++++++++++++-------------- 23 files changed, 669 insertions(+), 302 deletions(-) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/BundleIcon.icns create mode 100644 cmake/CTestConfig.cmake create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/CustomVolumeIcon.icns create mode 100644 cmake/Info.plist create mode 100644 cmake/MultiCPackConfig.cmake create mode 100644 cmake/README.txt create mode 100644 cmake/Welcome.txt create mode 100644 cmake/config.h.in create mode 100644 demo/CMakeLists.txt create mode 100644 src/CMakeLists.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..460ecb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*build* +*_export.h +.idea diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..15b4860 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,98 @@ +cmake_minimum_required(VERSION 3.0) +project(stdarc_c VERSION 0.0.1 LANGUAGES C) + +set(CMAKE_C_STANDARD 90) +cmake_policy(SET CMP0063 NEW) +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) + +option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) +if (BUILD_SHARED_LIBS) + set(LIBRARY_TYPE_FLAG "SHARED") +else () + set(LIBRARY_TYPE_FLAG "STATIC") +endif () + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +add_library("${PROJECT_NAME}_compiler_flags" INTERFACE) +target_compile_features("${PROJECT_NAME}_compiler_flags" INTERFACE "c_std_${CMAKE_C_STANDARD}") + +set(gcc_like "$") +set(msvc "$") +# -g -fsanitize=address -fno-omit-frame-pointer +target_compile_options( + "${PROJECT_NAME}_compiler_flags" + INTERFACE + "$<${gcc_like}:$>" + "$<${msvc}:$>" +) +if (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") +endif() + +# configure a header file to pass the version number only +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.h.in" + "${PROJECT_NAME}Config.h" +) + +add_subdirectory("src") + +option(BUILD_DEMOS "Build demos" ON) +if (BUILD_DEMOS) + add_subdirectory("demo") +endif (BUILD_DEMOS) + +install( + FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.h" + DESTINATION "include" +) + +include(InstallRequiredSystemLibraries) +set(CPACK_BUNDLE_NAME "${PROJECT_NAME}") +set(CPACK_PACKAGE_VENDOR "r-lyeh") +set(CPACK_PACKAGE_DESCRIPTION "Small file archivers (zip, pak, tar), virtual filesystem (vfs) and dir listing in a single-file header.") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Collection of small public domain file archivers") +if (APPLE) + set(CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist") + set(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Info.plist") + set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CustomVolumeIcon.icns") +endif() +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") +set(CPACK_PACKAGE_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/cmake/README.txt") +set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Welcome.txt") +set(CPACK_PACKAGE_CONTACT "https://github.com/r-lyeh/stdarc.c") + +include(CPack) +include(CMakePackageConfigHelpers) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) +if (BUILD_SHARED_LIBS) + set(LIBRARY_TYPE_FLAG "SHARED") +else () + set(LIBRARY_TYPE_FLAG "STATIC") +endif () + +# generate the config file that is includes the exports +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO +) + +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion +) diff --git a/cmake/BundleIcon.icns b/cmake/BundleIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..8808dd62db64540292417e8865bdf627aaf8792e GIT binary patch literal 33452 zcmeHOdvsOhmH+ND3E@$o&e9H@%&P5L{1ctwU<;)Zs`WM6I?kfg89Hmm+L^0ZX+AG~=i2H|SAQD9-)Q>fD~)-u>8^1*OsmxG8t_@661U4VtWdGrGhpEVfg-oZ zqz$XkEe8CC%M4iq1#V%=&5)H3X~1xsA&B#&7*PI@uyUoj)9l2a!x{)kozrJp0Vw@$ zC(r}JVVM4q+Zu4Y%>v;y{8lLB9w;$fKH!xNh!7DoiI`z9F<~+>VJKokm_#gKI3Z$Q ze#nScuHh08YE~x6ZC2QG7+~cz4WHii!!JArk@6Qm@Z-~z0+ypwGxAy%0&d!jEZRb> zBqPgTEL@=DD>WQUX61qvKSB=E#n69L1QCB+6=6ZlKJ7*x5wp*`VS|``y{ipk_QShu z5VIe-O9nCf(Yu59?z#OtxF&QQ{MhW|m+O)c^h*1HUo)->L9eW9{L1-M2zsrCPkMzy zetIFio%C{rLYL^377BepuNk4xReELd>sn4IbZvDg^eO!>>_7jc`CtARUDNI_?ib>X zO~Tpd`=5=1E<01W`wY|SuM=*c;R{){!rN!iM*jxk_0d+yS}#Ojz`)sB{WU`Pu!#%O zs)jVzaMNc0I*4-(T)?=9t02#l+YYOLEfm->>FTb8B42Jpu?7n4_;aDCfT943T&xKF z?hq;l#yT4n40=c~BT@NsANh$2w&h z)j%^X%P$=LW-Xi#AjMbf1{#G9v>^kH3m0s$W^kZ!vbAy_%M${PD;^7#@ToxKx>kV( zn2+NO2ZjnWu6rK`nN~^_;#>$Rzy)&oRN>8okb+xiPyJbQ3_7b1jzvnGCY!#wJBMPpa?$>z0Eli;ar4&cJqDK>(xZ z2dQHKM$r$Ujsh4(KcqSWU=;l@Y8zk_{jh3vtqiZ11|z6RKayH99LYdmcEkU_{D+U+ zD1`IwXbXp*_Ni~u@6N z^1d77I@6@ny+r~|se!m1@Zr`|h)9+WaNPaa7 zZ=tJMcne*FbLkRPhy432KC$sx{s=Xj-Ut3D90Q$ug)`{u+e1y1xm&n{XqWnS2{*Nt z=1$=a%5Jl7hrr~BX47mIBFN3A)g*EaG+O3%h*YO(Z4+oGsr@pyLdx3?%i1EivlM0{ z#JbD08U**1!mNiF+dk?st<9p4+7y6nf|$1<-YAM7M&n1#TCmuluF|R#C2&YWbZkN1 zh8V5dKq(aHG)-(nfv%8xNa~9*t2%w17FtXbdq8sGK8{^zadRFh#$b%5$tr>#`@tf^ zu?1}aT2`_^cQH_i zAN>@1g)N zXnA$NObs-K|5|B4;VeL|4Fi(}X7&JiK=*+my#dV$CVJ|J99xX7Xqo+_5{1n;iT*sX zW8jjoYsH{iLBl6&#So|!zu^$Rozk}xP16oRW4-WkrTEce%0hvJ3k5BjEE8(gxJb~Q z$qK>$KB|ub^uq$hL4C3CQE3#SPZFq$BKqG)RZ&F!DM|um00|caPFL0g{`YY;pygGi zK+Uf%1cStO9r#EUt^?USN0b5WQ$KH)fe+nwbQPG?e@9dSB`T^2pr#_oH$0d{WEo&o zQdNM4)N;xy5SVOaKZ+!yg|}R&1A`19MxKSQ)Ixe_$btYDq41ScBTg1n2@sf-5D-5i zjZ#2;TNsJxbh#9Sxq&PwWU>}~n=FT4Mq5^buYt5k85&f_7IPaZVO!X24z2^aW|%%% z2bPcOz)j;S3c(wsj-Cp^i_^sxmx9HmfMJuixEQ#RM>$Xw=mQ*864<6P*#bG5ec9E^ zg#+7M8u(a-w`F;t#iw2#1%et^eZ5>du+3$Hi^H-DMGlsAuq}oklFDMiHWko%EQ)3c z@5qWN#Woj=R5&{Af+?|_ot>&)pu=ZPST@4-VmX><*--TYgF=iMv})M(QfOh#P}KrG zsMC@GLb6&c4@R$uYJmk$K3F!IXxWG;7%GH(eAq;5hpHKvWB!0I%+pQbvO(Ao8dMDQ z7(#rA8CMHVvjGaMKm$mdfq0`vTtQ50xJulaxahVr~N92H#kuE0Z z&u;$4=pOgOF(mW0aaoQ{MF*}IU-ZmejgE;LY%*W&)PWveHF*u0R zKE`}h2XWdDG9Sf3oc2SQkLVyy`ytJTcQB0kuvh+Y_QM=7ta;q_Lmn_Z{Lp7SlKl`4 zMl_Gxe$W9U!w)`#(d=U!jA|aYebfP?!$+UNSnMMljLAH1d;5T~!H3UatoF*mn9Y-J zAFqSBZu#RgUj9=WtiODejt<%X4hm1`^;b7n?fJ9tod3;#ZK*5%vq(Gl>z6mKYdRGA zlSnIDTk*utf*prG6d9q{cRlmePyX|{Bdypu|C`=#-(6H)UtjZ~$UOJ!6L&2sHyayw z9SRMI%(AtGIZMhLy1I{b9C}|&qvKY7V@dgz-j|OZX@!7}{l@$y<;_>F?5VGLU(BH6 z4I`(p@qa(u+t9Rs&lNF)Fbw1CzSUQ*o_n$7;P!XLOvW*cg%AGx51;g%Ykjr}LdIfY z=;JH9HrBi=T!a@eGRZI$V#s%diy&<&qh6-7Cw3%Xwi4D13^@bi(}ej89=MDr$`boB zV;30C`!0R#4|y2-ZN@GzGVeOp_X$4lk&OE_Hsp66`PIi78*;`jFkB?p*!_%M#L|EU ze~ZDxVn%;cqlXnt9SVk5id;qgO@_yl@H<-1UCq<*Z!kQ>OV;iE5MqYEsNqRb-b@OH zhl1giB45E@WcV^RFVOI>F??9e@O>H{3Q9Zd86FCThk}w{sNnk;zQS-(Qj0YFs|+6& zGyDY&A676t6b!Ev#R~oc!&d?xRZybg&oey4R0I$+{L31?%5dEGJBS$^Vg{GuQU(1o zLs!d^Db>j57`fVTQOVfIy+A(SgnER6YQx5c;{3&vxN4L_qxS;+m1B3UXY(=*-vju{ zf}F6JiJ#W+P*4@Xo~c8@@K8`4lq>S58NQaYTA|@jGJIIf@Fz5USi$g6FuYQ%QSc`i z-sB>v)bL#l4>6Sh#0-C2!$Uz;00qNC!SG74R>2=<_)TnHrQtgmJ}hSVb`2j^Fgz3t zuN3PPe7lDC%wMo%dEmWj?cj)Z;90nAd1LTTP_T>VwF}coyJhj6k3F@g{Ua#Z4V3yU z(iR7*4zvc_KdMo#p4WlOxFzSl>TO3mTG~HauidrjaAo8a)*d?AMh8O4E?czAT4U-h zIp40^+1}9-47PvpagFv13!NM<0G@AeYxM_RhhFOYM0;;x@9T|>`3t^&+x;7wfe~O6 zo5XWWV!e^RaM>dpo1Q(`+L{}5!p{cHJ=do_b9!^7b(vk{mAESN%-;g&flXM;M$U@tSM zLi$u56oRQa>}C#C2E~$+p%7reBz9^N6*8PT_sNu0upd}45m+&i3JU0d6s7 z2c2!lKH98EZfBAeF!dIQDW16to-S=@3bqD=f!6$>qy3|LO%)&Q(wZeL3&nJA`pg?{ zy$6>_i=>>VY?*MQCR}28=G~N?J=aqrrhDc_(e|q&m^6-H()h4Fd#c}CCT4k~dE=`1 zs6nxAWY)OH&AVx?r&^@jyd`R*=3LL5@sWM@RPTB*)h10~uwu5GG+W$~3D2ZB5ZC&x z```PxLB|zlOtDD9Z4y(M;jQ28?E6GB+az2kt@b+=(pHh-nY(z~kxRcH_~WN`(oNxd z^rtHpG0b+6?#=j%tUJHA@!%irgx3t6r;djnVLqUEr`5S;E= zFh7sOwi~3+ELuM6VR?kPV(svhpy@o=C7LJ165zWiKRaP-CJQhF-k4F)M z4JWWtWOBF+gP=}Eu`1N8D#a9LWf*`u9mPraF_j{NI5AFdG$p$ys}SjwKM8X#ijm!) zm7yJ%2_!xj#B8chl{?wO9_al;s6?bQAFz29hbSfzSr}>6Thh6vKjl|U9s!c z-@oR5^U`no{~OPi`mek%`pfVH_Yd#B=Rgy#rjt+XDJ3L^nN!ZKE!?E$l-wJ?vcsNJ zR$TX&=Kdx%r!2bpZ*Ke6LN%vQ=x=_^o>M5uUucS$Qy}nOhhyzIg#_uherw_TSQF%2 zk(TZC%)RMh8dKCv0g3QlUq@4lJx`EKe16TA&5&_h7%-$PebH?T)r^v7WRMl3y~Aj9 zp?UqnE%7dEJShzb7Xd=ZfLch1_GE&i@x@MtvPC{f|3bWgsSEUlK?6- zQ8h(Kp+-HSQKht!K_O&NEhI=aJ8UAzN)4$d2Ps^uh#uFFQi|oCG6W$*Y9T?Yd7+*l zt2CsV7Nl^Uf@}{%VlteUhC2;`LaaeCM=qTTF~LU92@g%j-HVeSJttIOSEJyc*YKv1 z&VB0UIo=xf0iBLT22TlF7gL8KJ=tSIrfyHS-Jb2W{n>*;rXCbXt-ZErueHXs@T5Q% zxOLO%!GK-Y%H~!L3d(>^w1vB-*g0X_U4IJ*boHu!L{RG z@1BA#gJ?j{H0(YfW5TW<|I<|HiNz38!mh`cL8}<-=VG>x#*{#MeCbmzxqG$y$RU9Y z&{dIp=-GY5h@jNueaH!c^~(Ql_8&DNkikYpV5cU4#{QPY_IR*+)q~T}{1F9MFojCP zyEvdngJ(DRXTg9-sL6mQj5{8v*?v^b1_w45&fcU0p=N^$W7@)HKYI4)$?ik;bU=2S z6`$>zPnj`m{x`n$*e|;*tLO0Z$Gf_YxAJswps{2&I$@#)W2RPScozM5^`Wk_e#_C* zu|->3&MfJMPkndoa>#|lvB+$4}9~luAezQ-CM_mU)t0H{_0$hx)kvrk;0I{`8{BzcUSrEUvdLz)#%Ks!2m{_*#lNaZ}*EwgOZqD zoUn#5F^mSB(Y7dJYnd3#m>A4Bm2J_)a7UqNVZ9_`Hdsdlv2sn!o(vRJMRJHfPq75Pt4ywHjeEj1nB<0NFTmw@WaRJiPB zsX}DXaKI_-C74qubhLEqq^5)KFD9G|QH1a_q|dL}dWxol45GC7`&0@Stl5-4O-G3I zMc?gH^TDxyxO2rXyI!+qgxO@yz2iL12Wd~|7L=_!(sdTv2p*YV+^!~sXKEU{-a3`h z)v)H?g|q*9BTWeIM^`;lWA-fU%70mJs|XLu0Kfv9uV*#Yeq4W&b%EtNawm-#vaTU!^st!FA!c-2 ztl;0$@JgYFk~cLxzF0=^YAk`6;lpBrhnV3ZK6>xGv^>rJ4Gj;)ajcE{dbp_JOCU$K z)QAEx!-vHL4>7~rV#WS74X+f1Y8CI(@MZXt6>=XrSWr?Sru?gm9M%jEF;zg3X8)>& zSBj_+gECve2Sg4T1RoX?`wJSL#HfRaQA4E`3aW&taf9HiEJw=?k>dt|Yau~n24Ut^ zvS>;*@pGDZ6&H<0mQ%+*AXjr%6}Fr^eg*8Xn9w0U_ew7=A6u-#-UIl`S`@re=%x2G z!hW9M*K--Du?FJv7YQC>Dgt{1QSc;24MdC~3SKFqMiGLq=9WLqSy#HI@*($ytpYOb9+KCivqT-WIFibm-tHMbwBw@S7MOcRacgwd>%7#RLyA z$DYL7N@n9esz(&X9*Q$98>2@Qg5PX;(1pd!C&V9ZOz(@wTcf5E<)jvOtutrN_H=f% zP-kU3Yt!cfgERa09Xo!gRW?<+324y?ueGN2p6TAZ=LLF}p#~5-I~Z{4Yc21Y{d4dA#iNo>P zdDLj4+~a3yI8sd>=%zT>`}O%(Lw&fdbcn%(+~Qz_9G~IGP9@|P*9e6@tfkY&%)+N# ziKM8=+ZM|CZtc91Vkd)-M;C(z6CzM$dCu&k;Nz)9>{vn^sx0@}WBj}#YA8`8%Fsul z**J3i__3kK5|w~5YZ|ql_pNw(-|&M8@hP)r^>(+fd3r(A=l=+O>|jFV%BYFJUHQA93w=FIg}MLo(;;Hm=Zbp;ez?)L93 zo{kGM{1j%0xrMkFprDXTg07`cvtbZ;J^t@$$Mh%LhH$jnUhZdEs9 zTuq_#ZFP+R@=#T*`rJ8Q`k**}@j`=C$O>>mL9U@-*8!bu-00XJKDJ|lGBOaE{mJkj8U4wqfLQ;jt$^6< zr#b_%*-y3q*yyLa0*3ORx(XO7`>D*pP}xtV|DmFv$_g0He`+dVxa_AY1H)xMRsM&I zeyS>9B>%~;fRVDFiVTdD{Z#lLDf+3XfYJOXw*p4XezG$#TK1Fef3)Z)y8_1IKY0}} zmh2}p17pd4GX0Mw`pK+-vHDL=1&lTO$;!Z3v!5*gV~u{YDj**JiLZcovY(6$#FPDG z_>U+0$*6#M{U^2p;>~`dGZ1g~6YW3V=qI`Y#^XP66)>LcCo%)$$$ldJk0<(xtbp?gwiM53RF3Ye(>iB-Tvvp>-c zOf>rw^*_<*PqYFO;eY%UkcjM0Bm;@a{zUvIBKi}lfJFHpUj-y8`{T_(qOw0;|A~tJ zcq<^0{^PHJL}q_H8AxRI$KyYd(H~C*B-(#`6_Duc$D4sfXFp#5iH?4}6_5=7W3PZ@ zWIvt^BqRIr_)kXk+`e{%{#cRrZJTpQ`8&R{^Q?Kez%?nf;+6kjm_n|JVqmGWz5{_BS)1`RAyl?mhZ9 tOR28E*!-vZ`iu211pSsWm4C6nTBP5Srt)v{ezlppUr2uD>HmEM{tp8ay}tke literal 0 HcmV?d00001 diff --git a/cmake/CTestConfig.cmake b/cmake/CTestConfig.cmake new file mode 100644 index 0000000..ec92397 --- /dev/null +++ b/cmake/CTestConfig.cmake @@ -0,0 +1,7 @@ +set(CTEST_PROJECT_NAME "stdarc_c") +set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=stdarc_c") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 0000000..3048dc6 --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,4 @@ + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/libstdarc_cTargets.cmake" ) diff --git a/cmake/CustomVolumeIcon.icns b/cmake/CustomVolumeIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..3862a51917954ff9c92cfe8e7469c4b12525796b GIT binary patch literal 37827 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 literal 0 HcmV?d00001 diff --git a/cmake/Info.plist b/cmake/Info.plist new file mode 100644 index 0000000..e5a7d00 --- /dev/null +++ b/cmake/Info.plist @@ -0,0 +1,14 @@ + + + + + CFBundleExecutable + BundleGeneratorTest + CFBundleIconFile + BundleGeneratorTest.icns + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + + diff --git a/cmake/MultiCPackConfig.cmake b/cmake/MultiCPackConfig.cmake new file mode 100644 index 0000000..e8f89de --- /dev/null +++ b/cmake/MultiCPackConfig.cmake @@ -0,0 +1,6 @@ +include("release/CPackConfig.cmake") + +set(CPACK_INSTALL_CMAKE_PROJECTS + "debug;stdarc_c;ALL;/" + "release;stdarc_c;ALL;/" +) diff --git a/cmake/README.txt b/cmake/README.txt new file mode 100644 index 0000000..48ff566 --- /dev/null +++ b/cmake/README.txt @@ -0,0 +1 @@ +Small file archivers (zip, pak, tar), virtual filesystem (vfs) and dir listing in a single-file header. diff --git a/cmake/Welcome.txt b/cmake/Welcome.txt new file mode 100644 index 0000000..e76cf2d --- /dev/null +++ b/cmake/Welcome.txt @@ -0,0 +1,3 @@ +Small file archivers (zip, pak, tar), virtual filesystem (vfs) and dir listing in a single-file header. + +https://github.com/r-lyeh/stdarc.c diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 0000000..b4c9a53 --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,9 @@ +#ifndef stdarc_c_CONFIG_H +#define stdarc_c_CONFIG_H + +#define stdarc_c_VERSION_MAJOR @stdarc_c_VERSION_MAJOR@ +#define stdarc_c_VERSION_MINOR @stdarc_c_VERSION_MINOR@ +#define stdarc_c_VERSION_PATCH @stdarc_c_VERSION_PATCH@ +#define stdarc_c_VERSION "@stdarc_c_VERSION@" + +#endif /* stdarc_c_CONFIG_H */ diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt new file mode 100644 index 0000000..d5d9413 --- /dev/null +++ b/demo/CMakeLists.txt @@ -0,0 +1,35 @@ +set(exec_name_prefix "stdarc") + + +foreach(name "dir" "pak" "tar" "vfs" "zip") + set(EXEC_NAME "${exec_name_prefix}_${name}") + set(Source_Files "demo_${name}.c") + source_group("Source Files" FILES "${Source_Files}") + + add_library("${EXEC_NAME}" "${LIBRARY_TYPE_FLAG}" "${Source_Files}") + + target_include_directories( + "${EXEC_NAME}" + PUBLIC + "$" + "$" + ) + set_target_properties( + "${EXEC_NAME}" + PROPERTIES + LINKER_LANGUAGE + C + ) + target_link_libraries("${EXEC_NAME}" PRIVATE "${LIBRARY_NAME}") + + # install rules + + set(installable_libs "${EXEC_NAME}" "${PROJECT_NAME}_compiler_flags") + + if (TARGET "${DEPENDANT_LIBRARY}") + list(APPEND installable_libs "${DEPENDANT_LIBRARY}") + endif () + install(TARGETS ${installable_libs} + DESTINATION "bin" + EXPORT "${EXEC_NAME}Targets") +endforeach() diff --git a/demo/demo_dir.c b/demo/demo_dir.c index bf17fb2..3bb0039 100644 --- a/demo/demo_dir.c +++ b/demo/demo_dir.c @@ -8,7 +8,8 @@ int main(int argc, char **argv) { printf("list contents of %s ...\n", fname); dir *t = dir_open(fname, "rb"); if( t ) { - for( unsigned i = 0 ; i < dir_count(t); ++i ) { + unsigned i; + for( i = 0 ; i < dir_count(t); ++i ) { printf("Y %3d) %11u %s\t%s\n", i+1, dir_size(t,i), dir_name(t,i), dir_file(t,i) ? "" : ""); } dir_close(t); diff --git a/demo/demo_pak.c b/demo/demo_pak.c index f800723..c7fc9eb 100644 --- a/demo/demo_pak.c +++ b/demo/demo_pak.c @@ -10,7 +10,8 @@ int main(int argc, char **argv) { pak *z = pak_open("demo.pak", "a+b"); if( z ) { const char *fname = __FILE__; - for( FILE *fp = fopen(fname, "rb"); fp; fclose(fp), fp = 0) { + FILE *fp; + for( fp = fopen(fname, "rb"); fp; fclose(fp), fp = 0 ) { pak_append_file(z, fname, fp); } pak_close(z); @@ -21,7 +22,8 @@ int main(int argc, char **argv) { printf("testing files in %s ...\n", fname); z = pak_open(fname, "rb"); if( z ) { - for( unsigned i = 0 ; i < pak_count(z); ++i ) { + unsigned i; + for( i = 0 ; i < pak_count(z); ++i ) { printf(" %d) ", i+1); printf("@%08x ", pak_offset(z,i)); printf("%11u ", pak_size(z,i)); diff --git a/demo/demo_tar.c b/demo/demo_tar.c index ab53b8b..b7e3b14 100644 --- a/demo/demo_tar.c +++ b/demo/demo_tar.c @@ -8,7 +8,8 @@ int main(int argc, char **argv) { printf("list contents of %s ...\n", fname); tar *t = tar_open(fname, "rb"); if( t ) { - for( unsigned i = 0 ; i < tar_count(t); ++i ) { + unsigned i; + for( i = 0 ; i < tar_count(t); ++i ) { printf(" %d) @%08x %11u %s ", i+1, tar_offset(t,i), tar_size(t,i), tar_name(t,i)); void *data = tar_extract(t,i); printf("\r%c\n", data ? 'Y':'N'); // use data here: "%.*s\n",tar_size(t,i),(char*)data diff --git a/demo/demo_zip.c b/demo/demo_zip.c index 79c1aaa..7e692d4 100644 --- a/demo/demo_zip.c +++ b/demo/demo_zip.c @@ -13,7 +13,8 @@ int main(int argc, const char **argv) { zip *z = zip_open("demo.zip", "a+b"); if( z ) { // compress with DEFLATE|6. Other compressors are also supported (try LZMA|5, ULZ|9, LZ4X|3, etc.) - for( FILE *myfile = fopen(__FILE__, "rb"); myfile; fclose(myfile), myfile = 0) { + FILE *myfile; + for( myfile = fopen(__FILE__, "rb"); myfile; fclose(myfile), myfile = 0 ) { zip_append_file(z, __FILE__, myfile, 6); } zip_close(z); @@ -26,7 +27,8 @@ int main(int argc, const char **argv) { printf("testing files in %s ...\n", infile); z = zip_open(infile, "rb"); if( z ) { - for( unsigned i = 0 ; i < zip_count(z); ++i ) { + unsigned i; + for( i = 0 ; i < zip_count(z); ++i ) { printf(" %d) ", i+1); printf("[%08X] ", zip_hash(z,i)); printf("$%02X ", zip_codec(z,i)); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..e5bacb0 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,51 @@ +set(LIBRARY_NAME "stdarc") + +set(Header_Files "arc.h") +source_group("Header Files" FILES "${Header_Files}") + +set(Source_Files + "dir.c" + "pak.c" + "tar.c" + "vfs.c" + "zip.c" + ) +source_group("Source Files" FILES "${Source_Files}") + +add_library("${LIBRARY_NAME}" "${LIBRARY_TYPE_FLAG}" "${Header_Files}" "${Source_Files}") + +target_include_directories( + "${LIBRARY_NAME}" + PUBLIC + "$" + "$" +) +set_target_properties( + "${LIBRARY_NAME}" + PROPERTIES + LINKER_LANGUAGE + C +) + +# Symbol exporter +include(GenerateExportHeader) +set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/${LIBRARY_NAME}_export.h") +generate_export_header("${LIBRARY_NAME}" EXPORT_FILE_NAME "${_export_file}") + +################# +# install rules # +################# + +# setup the version numbering +set_property(TARGET "${LIBRARY_NAME}" PROPERTY VERSION "1.0.0") +set_property(TARGET "${LIBRARY_NAME}" PROPERTY SOVERSION "1") + +set(installable_libs "${LIBRARY_NAME}" "${PROJECT_NAME}_compiler_flags") +install(FILES "${Header_Files}" "${_export_file}" DESTINATION "include") + +if (TARGET "${DEPENDANT_LIBRARY}") + list(APPEND installable_libs "${DEPENDANT_LIBRARY}") +endif () +install(TARGETS ${installable_libs} + DESTINATION "bin" + EXPORT "${LIBRARY_NAME}Targets") diff --git a/src/dir.c b/src/dir.c index 11c46ec..b6189cd 100644 --- a/src/dir.c +++ b/src/dir.c @@ -71,31 +71,39 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { #ifdef _WIN32 WIN32_FIND_DATAA fdata = { 0 }; snprintf(name, namelen, "%s/*", pathfile); - for( HANDLE h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; (ok = FindClose( h ), h = INVALID_HANDLE_VALUE, 1)) { - for( int next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { - if( fdata.cFileName[0] == '.' ) continue; - int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; - snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); - struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; - // add - dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; - d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); - d->entry[d->count-1] = de; + HANDLE h; + { + for( h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; (ok = FindClose( h ), h = INVALID_HANDLE_VALUE, 1) ) { + int next; + for( next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { + if( fdata.cFileName[0] == '.' ) continue; + int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; + snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); + struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; + // add + dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; + d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); + d->entry[d->count-1] = de; + } } } #else snprintf(name, namelen, "%s/", pathfile); - for( DIR *dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1)) { - for( struct dirent *ep; ep = readdir(dir); ) { - if( ep->d_name[0] == '.' ) continue; - snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); - struct stat st; if( stat(name, &st) < 0 ) continue; - DIR *tmp = opendir(ep->d_name); int is_dir = !!tmp; if(tmp) closedir(tmp); - // if( is_dir && recursive ) { dir_yield(d,name); } - // add - dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; - d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); - d->entry[d->count-1] = de; + DIR *dir; + { + for( dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1) ) { + struct dirent *ep; + for( ; ep = readdir(dir); ) { + if( ep->d_name[0] == '.' ) continue; + snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); + struct stat st; if( stat(name, &st) < 0 ) continue; + DIR *tmp = opendir(ep->d_name); int is_dir = !!tmp; if(tmp) closedir(tmp); + // if( is_dir && recursive ) { dir_yield(d,name); } + // add + dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; + d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); + d->entry[d->count-1] = de; + } } } #endif @@ -107,8 +115,14 @@ dir *dir_open(const char *pathfile, const char *mode) { dir *d = (dir*)REALLOC(0, sizeof(dir)), zero = {0}; *d = zero; char *clean = STRDUP( pathfile ); - for( int i = 0; clean[i]; ++i ) if(clean[i] == '\\') clean[i] = '/'; - for( int len = strlen(clean); clean[--len] == '/'; ) clean[len] = '\0'; + { + int i; + for( i = 0; clean[i]; ++i ) if(clean[i] == '\\') clean[i] = '/'; + } + { + size_t len; + for( len = strlen(clean); clean[--len] == '/'; ) clean[len] = '\0'; + } char buffer[2048]; dir_yield(d, clean, buffer, 2048); @@ -118,7 +132,8 @@ dir *dir_open(const char *pathfile, const char *mode) { } int dir_find(dir *d, const char *entryname) { - for( int i = d->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + int i; + for( i = d->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) if( 0 == strcmp(entryname, d->entry[i].filename)) return i; } return -1; @@ -143,7 +158,8 @@ unsigned dir_file(dir *d, unsigned index) { void *dir_read(dir *d, unsigned index) { if( d && index < d->count ) { void *data = 0; - for( FILE *fp = fopen(d->entry[index].filename, "rb"); fp; fclose(fp), fp = 0) { + FILE *fp; + for( fp = fopen(d->entry[index].filename, "rb"); fp; fclose(fp), fp = 0 ) { size_t len = d->entry[index].size; data = REALLOC(0, len); if( data && fread(data, 1, len, fp) != len ) { @@ -156,8 +172,11 @@ void *dir_read(dir *d, unsigned index) { } void dir_close(dir *d) { - for( int i = 0; i < d->count; ++i) { - REALLOC(d->entry[i].filename, 0); + { + int i; + for( i = 0; i < d->count; ++i ) { + REALLOC(d->entry[i].filename, 0); + } } dir zero = {0}; *d = zero; @@ -168,7 +187,8 @@ void dir_close(dir *d) { int main( int argc, char **argv ) { dir *d = dir_open(argc > 1 ? argv[1] : "./", "rb"); if( d ) { - for( int i = 0; i < dir_count(d); ++i ) { + int i; + for( i = 0; i < dir_count(d); ++i ) { if( dir_file(d,i) ) printf("%3d) %11d %s\n", i + 1, dir_size(d,i), dir_name(d,i)); else diff --git a/src/pak.c b/src/pak.c index 319f2f6..e3e16f2 100644 --- a/src/pak.c +++ b/src/pak.c @@ -17,6 +17,8 @@ #ifndef PAK_H #define PAK_H +#include + typedef struct pak pak; pak* pak_open(const char *fname, const char *mode /*a,r,w*/); @@ -45,6 +47,7 @@ void pak_close(pak*); #include #include #include +#include #ifndef REALLOC #define REALLOC realloc @@ -135,10 +138,13 @@ pak *pak_open(const char *fname, const char *mode) { goto fail; } - for( unsigned i = 0; i < num_files; ++i ) { - pak_file *e = &p->entries[i]; - e->offset = ltoh32(e->offset); - e->size = ltoh32(e->size); + { + unsigned i; + for( i = 0; i < num_files; ++i ) { + pak_file *e = &p->entries[i]; + e->offset = ltoh32(e->offset); + e->size = ltoh32(e->size); + } } if( mode[0] == 'a' ) { @@ -226,17 +232,20 @@ void pak_close(pak *p) { if(p->out) { // write toc uint32_t seek = 0 + 12, dirpos = (uint32_t)ftell(p->out), dirlen = p->count * 64; - for(unsigned i = 0; i < p->count; ++i) { - pak_file *e = &p->entries[i]; - // write name (truncated if needed), and trailing zeros - char zero[56] = {0}; - int namelen = strlen(e->name); - fwrite( e->name, 1, namelen >= 56 ? 55 : namelen, p->out ); - fwrite( zero, 1, namelen >= 56 ? 1 : 56 - namelen, p->out ); - // write offset + length pair - uint32_t pseek = htol32(seek); fwrite( &pseek, 1,4, p->out ); - uint32_t psize = htol32(e->size); fwrite( &psize, 1,4, p->out ); - seek += e->size; + { + unsigned i; + for( i = 0; i < p->count; ++i ) { + pak_file *e = &p->entries[i]; + // write name (truncated if needed), and trailing zeros + char zero[56] = {0}; + int namelen = strlen(e->name); + fwrite( e->name, 1, namelen >= 56 ? 55 : namelen, p->out ); + fwrite( zero, 1, namelen >= 56 ? 1 : 56 - namelen, p->out ); + // write offset + length pair + uint32_t pseek = htol32(seek); fwrite( &pseek, 1,4, p->out ); + uint32_t psize = htol32(e->size); fwrite( &psize, 1,4, p->out ); + seek += e->size; + } } // patch header @@ -251,8 +260,11 @@ void pak_close(pak *p) { if(p->out) fclose(p->out); // clean up - for(unsigned i = 0; i < p->count; ++i) { - pak_file *e = &p->entries[i]; + { + unsigned i; + for( i = 0; i < p->count; ++i ) { + pak_file *e = &p->entries[i]; + } } REALLOC(p->entries, 0); @@ -264,8 +276,11 @@ void pak_close(pak *p) { int pak_find(pak *p, const char *filename) { if( p->in ) { - for( int i = p->count; --i >= 0; ) { - if(!strcmp(p->entries[i].name, filename)) return i; + { + int i; + for( i = p->count; --i >= 0; ) { + if(!strcmp(p->entries[i].name, filename)) return i; + } } } return -1; @@ -328,14 +343,17 @@ int main(int argc, char **argv) { printf("listing %s archive ...\n", fname); p = pak_open(fname, "rb"); if( p ) { - for( unsigned i = 0; i < pak_count(p); ++i ) { - printf(" %d) @%08x %11u %s ", i+1, pak_offset(p,i), pak_size(p,i), pak_name(p,i)); - void *data = pak_extract(p,i); - printf("\r%c\n", data ? 'Y':'N'); - if(argc > 2 && data) - if(i == pak_find(p,argv[2])) - printf("%.*s\n", (int)pak_size(p,i), (char*)data); - free(data); + { + unsigned i; + for( i = 0; i < pak_count(p); ++i ) { + printf(" %d) @%08x %11u %s ", i+1, pak_offset(p,i), pak_size(p,i), pak_name(p,i)); + void *data = pak_extract(p,i); + printf("\r%c\n", data ? 'Y':'N'); + if(argc > 2 && data) + if(i == pak_find(p,argv[2])) + printf("%.*s\n", (int)pak_size(p,i), (char*)data); + free(data); + } } pak_close(p); } diff --git a/src/tar.c b/src/tar.c index 9eb352b..5ee79ed 100644 --- a/src/tar.c +++ b/src/tar.c @@ -8,7 +8,7 @@ typedef struct tar tar; tar *tar_open(const char *filename, const char *mode); - int tar_find(tar*, const char *entryname); // returns entry number; or <0 if not found. + unsigned int tar_find(tar*, const char *entryname); // returns entry number; or <0 if not found. unsigned tar_count(tar*); char* tar_name(tar*, unsigned index); unsigned tar_size(tar*, unsigned index); @@ -141,9 +141,12 @@ tar *tar_open(const char *filename, const char *mode) { return t; } -int tar_find(tar *t, const char *entryname) { - if( t->in ) for( int i = t->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) - if( 0 == strcmp(entryname, t->entries[i].filename)) return i; +unsigned int tar_find(tar *t, const char *entryname) { + if( t->in ) { + int i; + for( i = t->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + if( 0 == strcmp(entryname, t->entries[i].filename)) return i; + } } return -1; } @@ -177,8 +180,11 @@ void *tar_extract(tar *t, unsigned index) { void tar_close(tar *t) { fclose(t->in); - for( int i = 0; i < t->count; ++i) { - REALLOC(t->entries[i].filename, 0); + { + int i; + for( i = 0; i < t->count; ++i ) { + REALLOC(t->entries[i].filename, 0); + } } tar zero = {0}; *t = zero; @@ -190,7 +196,8 @@ int main( int argc, char **argv ) { if(argc <= 1) exit(printf("%s file.tar [file_to_view]\n", argv[0])); tar *t = tar_open(argv[1], "rb"); if( t ) { - for( int i = 0; i < tar_count(t); ++i ) { + unsigned i; + for( i = 0; i < tar_count(t); ++i ) { printf("%d) %s (%u bytes)\n", i+1, tar_name(t,i), tar_size(t,i)); char *data = tar_extract(t,i); if(argc>2) if(0==strcmp(argv[2],tar_name(t,i))) printf("%.*s\n", tar_size(t,i), data); diff --git a/src/vfs.c b/src/vfs.c index f4691a5..511ac65 100644 --- a/src/vfs.c +++ b/src/vfs.c @@ -4,7 +4,7 @@ // - note: vfs_mount() order matters (the most recent the higher priority). void vfs_mount(const char *path); // zipfile or directory/with/trailing/slash/ -char* vfs_load(const char *filename, int *size); // must free() after use +char* vfs_load(const char *filename, unsigned int *size); // must free() after use // ----------------------------------------------------------------------------- @@ -55,15 +55,16 @@ void vfs_mount(const char *path) { dir_head->is_directory = is_directory; } -char *vfs_load(const char *filename, int *size) { // must free() after use +char *vfs_load(const char *filename, unsigned int *size) { // must free() after use char *data = NULL; - for(vfs_dir *dir = dir_head; dir && !data; dir = dir->next) { + vfs_dir *dir; + for( dir = dir_head; dir && !data; dir = dir->next ) { if( dir->is_directory ) { char buf[512]; snprintf(buf, sizeof(buf), "%s%s", dir->path, filename); data = vfs_read_file(buf, size); } else { - int index = zip_find(dir->archive, filename); + unsigned int index = zip_find(dir->archive, filename); data = zip_extract(dir->archive, index); if( size ) *size = zip_size(dir->archive, index); } diff --git a/src/zip.c b/src/zip.c index b15830c..b814082 100644 --- a/src/zip.c +++ b/src/zip.c @@ -11,6 +11,7 @@ #ifndef ZIP_H #define ZIP_H + #include #include @@ -22,7 +23,7 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/); bool zip_append_file(zip*, const char *entryname, FILE *in, unsigned compr_level); // only for (r)ead mode - int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. + unsigned int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. unsigned zip_count(zip*); char* zip_name(zip*, unsigned index); char* zip_modt(zip*, unsigned index); @@ -49,6 +50,7 @@ void zip_close(zip*); #include #include #include +#include #ifndef REALLOC #define REALLOC realloc @@ -186,7 +188,7 @@ int jzReadEndRecord(FILE *fp, JZEndRecord *endRecord) { } // Naively assume signature can only be found in one place... - for(i = readBytes - sizeof(JZEndRecord); i >= 0; i--) { + for( i = readBytes - sizeof(JZEndRecord); i >= 0; i-- ) { er = (JZEndRecord *)(jzBuffer + i); if(er->signature == 0x06054B50) break; @@ -225,84 +227,87 @@ int jzReadCentralDirectory(FILE *fp, JZEndRecord *endRecord, JZRecordCallback ca return ERR(JZ_ERRNO, "Cannot seek in zip file!"); } - for(int i=0; inumEntries; i++) { - PRINTF("%d)\n@-> %lu %#lx\n", i+1, (unsigned long)ftell(fp), (unsigned long)ftell(fp)); - long offset = ftell(fp); // store current position + { + uint16_t i; + for( i=0; inumEntries; i++ ) { + PRINTF("%d)\n@-> %lu %#lx\n", i+1, (unsigned long)ftell(fp), (unsigned long)ftell(fp)); + long offset = ftell(fp); // store current position - if(fread(&fileHeader, 1, sizeof(JZGlobalFileHeader), fp) < sizeof(JZGlobalFileHeader)) { - return ERR(JZ_ERRNO, "Couldn't read file header #%d!", i); - } + if(fread(&fileHeader, 1, sizeof(JZGlobalFileHeader), fp) < sizeof(JZGlobalFileHeader)) { + return ERR(JZ_ERRNO, "Couldn't read file header #%d!", i); + } - JZGlobalFileHeader *g = &fileHeader, copy = *g; - PRINTF("\tsignature: %u %#x\n", g->signature, g->signature); // 0x02014B50 - PRINTF("\tversionMadeBy: %u %#x\n", g->versionMadeBy, g->versionMadeBy); // unsupported - PRINTF("\tversionNeededToExtract: %u %#x\n", g->versionNeededToExtract, g->versionNeededToExtract); // unsupported - PRINTF("\tgeneralPurposeBitFlag: %u %#x\n", g->generalPurposeBitFlag, g->generalPurposeBitFlag); // unsupported - PRINTF("\tcompressionMethod: %u %#x\n", g->compressionMethod, g->compressionMethod); // 0-store,8-deflate - PRINTF("\tlastModFileTime: %u %#x\n", g->lastModFileTime, g->lastModFileTime); - PRINTF("\tlastModFileDate: %u %#x\n", g->lastModFileDate, g->lastModFileDate); - PRINTF("\tcrc32: %#x\n", g->crc32); - PRINTF("\tcompressedSize: %u\n", g->compressedSize); - PRINTF("\tuncompressedSize: %u\n", g->uncompressedSize); - PRINTF("\tfileNameLength: %u\n", g->fileNameLength); - PRINTF("\textraFieldLength: %u\n", g->extraFieldLength); // unsupported - PRINTF("\tfileCommentLength: %u\n", g->fileCommentLength); // unsupported - PRINTF("\tdiskNumberStart: %u\n", g->diskNumberStart); // unsupported - PRINTF("\tinternalFileAttributes: %#x\n", g->internalFileAttributes); // unsupported - PRINTF("\texternalFileAttributes: %#x\n", g->externalFileAttributes); // unsupported - PRINTF("\trelativeOffsetOflocalHeader: %u %#x\n", g->relativeOffsetOflocalHeader, g->relativeOffsetOflocalHeader); - - if(fileHeader.signature != 0x02014B50) { - return ERR(JZ_ERRNO, "Invalid file header signature %#x #%d!", fileHeader.signature, i); - } + JZGlobalFileHeader *g = &fileHeader, copy = *g; + PRINTF("\tsignature: %u %#x\n", g->signature, g->signature); // 0x02014B50 + PRINTF("\tversionMadeBy: %u %#x\n", g->versionMadeBy, g->versionMadeBy); // unsupported + PRINTF("\tversionNeededToExtract: %u %#x\n", g->versionNeededToExtract, g->versionNeededToExtract); // unsupported + PRINTF("\tgeneralPurposeBitFlag: %u %#x\n", g->generalPurposeBitFlag, g->generalPurposeBitFlag); // unsupported + PRINTF("\tcompressionMethod: %u %#x\n", g->compressionMethod, g->compressionMethod); // 0-store,8-deflate + PRINTF("\tlastModFileTime: %u %#x\n", g->lastModFileTime, g->lastModFileTime); + PRINTF("\tlastModFileDate: %u %#x\n", g->lastModFileDate, g->lastModFileDate); + PRINTF("\tcrc32: %#x\n", g->crc32); + PRINTF("\tcompressedSize: %u\n", g->compressedSize); + PRINTF("\tuncompressedSize: %u\n", g->uncompressedSize); + PRINTF("\tfileNameLength: %u\n", g->fileNameLength); + PRINTF("\textraFieldLength: %u\n", g->extraFieldLength); // unsupported + PRINTF("\tfileCommentLength: %u\n", g->fileCommentLength); // unsupported + PRINTF("\tdiskNumberStart: %u\n", g->diskNumberStart); // unsupported + PRINTF("\tinternalFileAttributes: %#x\n", g->internalFileAttributes); // unsupported + PRINTF("\texternalFileAttributes: %#x\n", g->externalFileAttributes); // unsupported + PRINTF("\trelativeOffsetOflocalHeader: %u %#x\n", g->relativeOffsetOflocalHeader, g->relativeOffsetOflocalHeader); + + if(fileHeader.signature != 0x02014B50) { + return ERR(JZ_ERRNO, "Invalid file header signature %#x #%d!", fileHeader.signature, i); + } - if(fileHeader.fileNameLength + 1 >= JZ_BUFFER_SIZE) { - return ERR(JZ_ERRNO, "Too long file name %u #%d!", fileHeader.fileNameLength, i); - } + if(fileHeader.fileNameLength + 1 >= JZ_BUFFER_SIZE) { + return ERR(JZ_ERRNO, "Too long file name %u #%d!", fileHeader.fileNameLength, i); + } - // filename - char jzFilename[JZ_BUFFER_SIZE/3]; - if(fread(jzFilename, 1, fileHeader.fileNameLength, fp) < fileHeader.fileNameLength) { - return ERR(JZ_ERRNO, "Couldn't read filename #%d!", i); - } - jzFilename[fileHeader.fileNameLength] = '\0'; // NULL terminate + // filename + char jzFilename[JZ_BUFFER_SIZE/3]; + if(fread(jzFilename, 1, fileHeader.fileNameLength, fp) < fileHeader.fileNameLength) { + return ERR(JZ_ERRNO, "Couldn't read filename #%d!", i); + } + jzFilename[fileHeader.fileNameLength] = '\0'; // NULL terminate - // extra block - unsigned char jzExtra[JZ_BUFFER_SIZE/3]; - if(fread(jzExtra, 1, fileHeader.extraFieldLength, fp) < fileHeader.extraFieldLength) { - return ERR(JZ_ERRNO, "Couldn't read extra block #%d!", i); - } + // extra block + unsigned char jzExtra[JZ_BUFFER_SIZE/3]; + if(fread(jzExtra, 1, fileHeader.extraFieldLength, fp) < fileHeader.extraFieldLength) { + return ERR(JZ_ERRNO, "Couldn't read extra block #%d!", i); + } - // comment block - char jzComment[JZ_BUFFER_SIZE/3]; - if(fread(jzComment, 1, fileHeader.fileCommentLength, fp) < fileHeader.fileCommentLength) { - return ERR(JZ_ERRNO, "Couldn't read comment block #%d!", i); - } - jzComment[fileHeader.fileCommentLength] = '\0'; // NULL terminate + // comment block + char jzComment[JZ_BUFFER_SIZE/3]; + if(fread(jzComment, 1, fileHeader.fileCommentLength, fp) < fileHeader.fileCommentLength) { + return ERR(JZ_ERRNO, "Couldn't read comment block #%d!", i); + } + jzComment[fileHeader.fileCommentLength] = '\0'; // NULL terminate - // seek to local file header, then skip file header + filename + extra field length - if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader - 2 - 2, SEEK_SET)) { - return ERR(JZ_ERRNO, "Cannot seek in file!"); - } + // seek to local file header, then skip file header + filename + extra field length + if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader - 2 - 2, SEEK_SET)) { + return ERR(JZ_ERRNO, "Cannot seek in file!"); + } - if(fread(&fileHeader.fileNameLength, 1, 2, fp) < 2) { - return ERR(JZ_ERRNO, "Couldn't read local filename #%d!", i); - } - if(fread(&fileHeader.extraFieldLength, 1, 2, fp) < 2) { - return ERR(JZ_ERRNO, "Couldn't read local extrafield #%d!", i); - } - if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader + fileHeader.fileNameLength + fileHeader.extraFieldLength, SEEK_SET)) { - return ERR(JZ_ERRNO, "Cannot seek in file!"); - } + if(fread(&fileHeader.fileNameLength, 1, 2, fp) < 2) { + return ERR(JZ_ERRNO, "Couldn't read local filename #%d!", i); + } + if(fread(&fileHeader.extraFieldLength, 1, 2, fp) < 2) { + return ERR(JZ_ERRNO, "Couldn't read local extrafield #%d!", i); + } + if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader + fileHeader.fileNameLength + fileHeader.extraFieldLength, SEEK_SET)) { + return ERR(JZ_ERRNO, "Cannot seek in file!"); + } - PRINTF("@-> %lu %#lx\n---\n", (unsigned long)ftell(fp), (unsigned long)ftell(fp)); + PRINTF("@-> %lu %#lx\n---\n", (unsigned long)ftell(fp), (unsigned long)ftell(fp)); - if( JZ_OK != callback(fp, i, &fileHeader, jzFilename, jzExtra, jzComment, user_data) ) - break; // keep going while callback returns ok + if( JZ_OK != callback(fp, i, &fileHeader, jzFilename, jzExtra, jzComment, user_data) ) + break; // keep going while callback returns ok - fseek(fp, offset, SEEK_SET); // return to position - fseek(fp, sizeof(JZGlobalFileHeader) + copy.fileNameLength, SEEK_CUR); // skip entry - fseek(fp, copy.extraFieldLength + copy.fileCommentLength, SEEK_CUR); // skip entry + fseek(fp, offset, SEEK_SET); // return to position + fseek(fp, sizeof(JZGlobalFileHeader) + copy.fileNameLength, SEEK_CUR); // skip entry + fseek(fp, copy.extraFieldLength + copy.fileCommentLength, SEEK_CUR); // skip entry + } } return JZ_OK; @@ -359,13 +364,20 @@ struct zip { uint32_t zip__crc32(uint32_t crc, const void *data, size_t n_bytes) { // CRC32 routine is from Björn Samuelsson's public domain implementation at http://home.thep.lu.se/~bjorn/crc/ static uint32_t table[256] = {0}; - if(!*table) for(uint32_t i = 0; i < 0x100; ++i) { - uint32_t r = i; - for(int j = 0; j < 8; ++j) r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; - table[i] = r ^ (uint32_t)0xFF000000L; + if(!*table) { + uint32_t i; + for( i = 0; i < 0x100; ++i ) { + uint32_t r = i; + unsigned short j; + for( j = 0; j < 8; ++j ) + r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; + table[i] = r ^ (uint32_t)0xFF000000L; + } } - for(size_t i = 0; i < n_bytes; ++i) { - crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; + { + size_t i; + for( i = 0; i < n_bytes; ++i ) + crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; } return crc; } @@ -392,9 +404,12 @@ int zip__callback(FILE *fp, int idx, JZGlobalFileHeader *header, char *filename, // zip read -int zip_find(zip *z, const char *entryname) { - if( z->in ) for( int i = z->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) - if( 0 == strcmp(entryname, z->entries[i].filename)) return i; +unsigned int zip_find(zip *z, const char *entryname) { + if( z->in ) { + int i; + for( i = z->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + if( 0 == strcmp(entryname, z->entries[i].filename)) return i; + } } return -1; } @@ -635,13 +650,16 @@ void zip_close(zip* z) { end.numEntries = z->count; end.centralDirectoryOffset = ftell(z->out); // flush global directory: global file+filename each - for(unsigned i = 0; i < z->count; i++) { - struct zip_entry *h = &z->entries[i]; - JZGlobalFileHeader *g = &h->header; - fwrite(g, 1, sizeof(JZGlobalFileHeader), z->out); - fwrite(h->filename, 1, g->fileNameLength, z->out); - fwrite(h->extra, 1, g->extraFieldLength, z->out); - fwrite(h->comment, 1, g->fileCommentLength, z->out); + { + unsigned i; + for( i = 0; i < z->count; i++ ) { + struct zip_entry *h = &z->entries[i]; + JZGlobalFileHeader *g = &h->header; + fwrite(g, 1, sizeof(JZGlobalFileHeader), z->out); + fwrite(h->filename, 1, g->fileNameLength, z->out); + fwrite(h->extra, 1, g->extraFieldLength, z->out); + fwrite(h->comment, 1, g->fileCommentLength, z->out); + } } end.centralDirectorySize = ftell(z->out) - end.centralDirectoryOffset; end.zipCommentLength = 0; @@ -652,10 +670,13 @@ void zip_close(zip* z) { if( z->out ) fclose(z->out); if( z->in ) fclose(z->in); // clean up - for(unsigned i = 0; i < z->count; ++i ) { - REALLOC(z->entries[i].filename, 0); - if(z->entries[i].extra) REALLOC(z->entries[i].extra, 0); - if(z->entries[i].comment) REALLOC(z->entries[i].comment, 0); + { + unsigned i; + for( i = 0; i < z->count; ++i ) { + REALLOC(z->entries[i].filename, 0); + if(z->entries[i].extra) REALLOC(z->entries[i].extra, 0); + if(z->entries[i].comment) REALLOC(z->entries[i].comment, 0); + } } if(z->entries) REALLOC(z->entries, 0); zip zero = {0}; *z = zero; REALLOC(z, 0); diff --git a/stdarc.c b/stdarc.c index e620110..6c9e5ad 100644 --- a/stdarc.c +++ b/stdarc.c @@ -40,7 +40,7 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/); bool zip_append_file(zip*, const char *entryname, FILE *in, unsigned compr_level); // only for (r)ead mode - int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. + unsigned int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. unsigned zip_count(zip*); char* zip_name(zip*, unsigned index); char* zip_modt(zip*, unsigned index); @@ -202,7 +202,7 @@ int jzReadEndRecord(FILE *fp, JZEndRecord *endRecord) { } // Naively assume signature can only be found in one place... - for(i = readBytes - sizeof(JZEndRecord); i >= 0; i--) { + for( i = readBytes - sizeof(JZEndRecord); i >= 0; i-- ) { er = (JZEndRecord *)(jzBuffer + i); if(er->signature == 0x06054B50) break; @@ -241,84 +241,92 @@ int jzReadCentralDirectory(FILE *fp, JZEndRecord *endRecord, JZRecordCallback ca return ERR(JZ_ERRNO, "Cannot seek in zip file!"); } - for(int i=0; inumEntries; i++) { - PRINTF("%d)\n@-> %lu %#lx\n", i+1, (unsigned long)ftell(fp), (unsigned long)ftell(fp)); - long offset = ftell(fp); // store current position + { + uint16_t i; + for (i = 0; i < endRecord->numEntries; i++) { + PRINTF("%d)\n@-> %lu %#lx\n", i + 1, (unsigned long) ftell(fp), (unsigned long) ftell(fp)); + long offset = ftell(fp); // store current position - if(fread(&fileHeader, 1, sizeof(JZGlobalFileHeader), fp) < sizeof(JZGlobalFileHeader)) { - return ERR(JZ_ERRNO, "Couldn't read file header #%d!", i); - } + if (fread(&fileHeader, 1, sizeof(JZGlobalFileHeader), fp) < sizeof(JZGlobalFileHeader)) { + return ERR(JZ_ERRNO, "Couldn't read file header #%d!", i); + } - JZGlobalFileHeader *g = &fileHeader, copy = *g; - PRINTF("\tsignature: %u %#x\n", g->signature, g->signature); // 0x02014B50 - PRINTF("\tversionMadeBy: %u %#x\n", g->versionMadeBy, g->versionMadeBy); // unsupported - PRINTF("\tversionNeededToExtract: %u %#x\n", g->versionNeededToExtract, g->versionNeededToExtract); // unsupported - PRINTF("\tgeneralPurposeBitFlag: %u %#x\n", g->generalPurposeBitFlag, g->generalPurposeBitFlag); // unsupported - PRINTF("\tcompressionMethod: %u %#x\n", g->compressionMethod, g->compressionMethod); // 0-store,8-deflate - PRINTF("\tlastModFileTime: %u %#x\n", g->lastModFileTime, g->lastModFileTime); - PRINTF("\tlastModFileDate: %u %#x\n", g->lastModFileDate, g->lastModFileDate); - PRINTF("\tcrc32: %#x\n", g->crc32); - PRINTF("\tcompressedSize: %u\n", g->compressedSize); - PRINTF("\tuncompressedSize: %u\n", g->uncompressedSize); - PRINTF("\tfileNameLength: %u\n", g->fileNameLength); - PRINTF("\textraFieldLength: %u\n", g->extraFieldLength); // unsupported - PRINTF("\tfileCommentLength: %u\n", g->fileCommentLength); // unsupported - PRINTF("\tdiskNumberStart: %u\n", g->diskNumberStart); // unsupported - PRINTF("\tinternalFileAttributes: %#x\n", g->internalFileAttributes); // unsupported - PRINTF("\texternalFileAttributes: %#x\n", g->externalFileAttributes); // unsupported - PRINTF("\trelativeOffsetOflocalHeader: %u %#x\n", g->relativeOffsetOflocalHeader, g->relativeOffsetOflocalHeader); - - if(fileHeader.signature != 0x02014B50) { - return ERR(JZ_ERRNO, "Invalid file header signature %#x #%d!", fileHeader.signature, i); - } + JZGlobalFileHeader *g = &fileHeader, copy = *g; + PRINTF("\tsignature: %u %#x\n", g->signature, g->signature); // 0x02014B50 + PRINTF("\tversionMadeBy: %u %#x\n", g->versionMadeBy, g->versionMadeBy); // unsupported + PRINTF("\tversionNeededToExtract: %u %#x\n", g->versionNeededToExtract, + g->versionNeededToExtract); // unsupported + PRINTF("\tgeneralPurposeBitFlag: %u %#x\n", g->generalPurposeBitFlag, + g->generalPurposeBitFlag); // unsupported + PRINTF("\tcompressionMethod: %u %#x\n", g->compressionMethod, g->compressionMethod); // 0-store,8-deflate + PRINTF("\tlastModFileTime: %u %#x\n", g->lastModFileTime, g->lastModFileTime); + PRINTF("\tlastModFileDate: %u %#x\n", g->lastModFileDate, g->lastModFileDate); + PRINTF("\tcrc32: %#x\n", g->crc32); + PRINTF("\tcompressedSize: %u\n", g->compressedSize); + PRINTF("\tuncompressedSize: %u\n", g->uncompressedSize); + PRINTF("\tfileNameLength: %u\n", g->fileNameLength); + PRINTF("\textraFieldLength: %u\n", g->extraFieldLength); // unsupported + PRINTF("\tfileCommentLength: %u\n", g->fileCommentLength); // unsupported + PRINTF("\tdiskNumberStart: %u\n", g->diskNumberStart); // unsupported + PRINTF("\tinternalFileAttributes: %#x\n", g->internalFileAttributes); // unsupported + PRINTF("\texternalFileAttributes: %#x\n", g->externalFileAttributes); // unsupported + PRINTF("\trelativeOffsetOflocalHeader: %u %#x\n", g->relativeOffsetOflocalHeader, + g->relativeOffsetOflocalHeader); + + if (fileHeader.signature != 0x02014B50) { + return ERR(JZ_ERRNO, "Invalid file header signature %#x #%d!", fileHeader.signature, i); + } - if(fileHeader.fileNameLength + 1 >= JZ_BUFFER_SIZE) { - return ERR(JZ_ERRNO, "Too long file name %u #%d!", fileHeader.fileNameLength, i); - } + if (fileHeader.fileNameLength + 1 >= JZ_BUFFER_SIZE) { + return ERR(JZ_ERRNO, "Too long file name %u #%d!", fileHeader.fileNameLength, i); + } - // filename - char jzFilename[JZ_BUFFER_SIZE/3]; - if(fread(jzFilename, 1, fileHeader.fileNameLength, fp) < fileHeader.fileNameLength) { - return ERR(JZ_ERRNO, "Couldn't read filename #%d!", i); - } - jzFilename[fileHeader.fileNameLength] = '\0'; // NULL terminate + // filename + char jzFilename[JZ_BUFFER_SIZE / 3]; + if (fread(jzFilename, 1, fileHeader.fileNameLength, fp) < fileHeader.fileNameLength) { + return ERR(JZ_ERRNO, "Couldn't read filename #%d!", i); + } + jzFilename[fileHeader.fileNameLength] = '\0'; // NULL terminate - // extra block - unsigned char jzExtra[JZ_BUFFER_SIZE/3]; - if(fread(jzExtra, 1, fileHeader.extraFieldLength, fp) < fileHeader.extraFieldLength) { - return ERR(JZ_ERRNO, "Couldn't read extra block #%d!", i); - } + // extra block + unsigned char jzExtra[JZ_BUFFER_SIZE / 3]; + if (fread(jzExtra, 1, fileHeader.extraFieldLength, fp) < fileHeader.extraFieldLength) { + return ERR(JZ_ERRNO, "Couldn't read extra block #%d!", i); + } - // comment block - char jzComment[JZ_BUFFER_SIZE/3]; - if(fread(jzComment, 1, fileHeader.fileCommentLength, fp) < fileHeader.fileCommentLength) { - return ERR(JZ_ERRNO, "Couldn't read comment block #%d!", i); - } - jzComment[fileHeader.fileCommentLength] = '\0'; // NULL terminate + // comment block + char jzComment[JZ_BUFFER_SIZE / 3]; + if (fread(jzComment, 1, fileHeader.fileCommentLength, fp) < fileHeader.fileCommentLength) { + return ERR(JZ_ERRNO, "Couldn't read comment block #%d!", i); + } + jzComment[fileHeader.fileCommentLength] = '\0'; // NULL terminate - // seek to local file header, then skip file header + filename + extra field length - if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader - 2 - 2, SEEK_SET)) { - return ERR(JZ_ERRNO, "Cannot seek in file!"); - } + // seek to local file header, then skip file header + filename + extra field length + if (fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader - 2 - 2, SEEK_SET)) { + return ERR(JZ_ERRNO, "Cannot seek in file!"); + } - if(fread(&fileHeader.fileNameLength, 1, 2, fp) < 2) { - return ERR(JZ_ERRNO, "Couldn't read local filename #%d!", i); - } - if(fread(&fileHeader.extraFieldLength, 1, 2, fp) < 2) { - return ERR(JZ_ERRNO, "Couldn't read local extrafield #%d!", i); - } - if(fseek(fp, fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader + fileHeader.fileNameLength + fileHeader.extraFieldLength, SEEK_SET)) { - return ERR(JZ_ERRNO, "Cannot seek in file!"); - } + if (fread(&fileHeader.fileNameLength, 1, 2, fp) < 2) { + return ERR(JZ_ERRNO, "Couldn't read local filename #%d!", i); + } + if (fread(&fileHeader.extraFieldLength, 1, 2, fp) < 2) { + return ERR(JZ_ERRNO, "Couldn't read local extrafield #%d!", i); + } + if (fseek(fp, + fileHeader.relativeOffsetOflocalHeader + sizeof_JZLocalFileHeader + fileHeader.fileNameLength + + fileHeader.extraFieldLength, SEEK_SET)) { + return ERR(JZ_ERRNO, "Cannot seek in file!"); + } - PRINTF("@-> %lu %#lx\n---\n", (unsigned long)ftell(fp), (unsigned long)ftell(fp)); + PRINTF("@-> %lu %#lx\n---\n", (unsigned long) ftell(fp), (unsigned long) ftell(fp)); - if( JZ_OK != callback(fp, i, &fileHeader, jzFilename, jzExtra, jzComment, user_data) ) - break; // keep going while callback returns ok + if (JZ_OK != callback(fp, i, &fileHeader, jzFilename, jzExtra, jzComment, user_data)) + break; // keep going while callback returns ok - fseek(fp, offset, SEEK_SET); // return to position - fseek(fp, sizeof(JZGlobalFileHeader) + copy.fileNameLength, SEEK_CUR); // skip entry - fseek(fp, copy.extraFieldLength + copy.fileCommentLength, SEEK_CUR); // skip entry + fseek(fp, offset, SEEK_SET); // return to position + fseek(fp, sizeof(JZGlobalFileHeader) + copy.fileNameLength, SEEK_CUR); // skip entry + fseek(fp, copy.extraFieldLength + copy.fileCommentLength, SEEK_CUR); // skip entry + } } return JZ_OK; @@ -375,13 +383,20 @@ struct zip { uint32_t zip__crc32(uint32_t crc, const void *data, size_t n_bytes) { // CRC32 routine is from Björn Samuelsson's public domain implementation at http://home.thep.lu.se/~bjorn/crc/ static uint32_t table[256] = {0}; - if(!*table) for(uint32_t i = 0; i < 0x100; ++i) { - uint32_t r = i; - for(int j = 0; j < 8; ++j) r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; - table[i] = r ^ (uint32_t)0xFF000000L; + if(!*table) { + uint32_t i; + for (i = 0; i < 0x100; ++i) { + uint32_t r = i; + unsigned short j; + for (j = 0; j < 8; ++j) r = (r & 1 ? 0 : (uint32_t) 0xEDB88320L) ^ r >> 1; + table[i] = r ^ (uint32_t) 0xFF000000L; + } } - for(size_t i = 0; i < n_bytes; ++i) { - crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; + { + size_t i; + for (i = 0; i < n_bytes; ++i) { + crc = table[(uint8_t) crc ^ ((uint8_t *) data)[i]] ^ crc >> 8; + } } return crc; } @@ -408,9 +423,12 @@ int zip__callback(FILE *fp, int idx, JZGlobalFileHeader *header, char *filename, // zip read -int zip_find(zip *z, const char *entryname) { - if( z->in ) for( int i = z->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) - if( 0 == strcmp(entryname, z->entries[i].filename)) return i; +unsigned int zip_find(zip *z, const char *entryname) { + if( z->in ) { + unsigned i; + for ( i = z->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + if (0 == strcmp(entryname, z->entries[i].filename)) return i; + } } return -1; } @@ -651,13 +669,16 @@ void zip_close(zip* z) { end.numEntries = z->count; end.centralDirectoryOffset = ftell(z->out); // flush global directory: global file+filename each - for(unsigned i = 0; i < z->count; i++) { - struct zip_entry *h = &z->entries[i]; - JZGlobalFileHeader *g = &h->header; - fwrite(g, 1, sizeof(JZGlobalFileHeader), z->out); - fwrite(h->filename, 1, g->fileNameLength, z->out); - fwrite(h->extra, 1, g->extraFieldLength, z->out); - fwrite(h->comment, 1, g->fileCommentLength, z->out); + { + unsigned i; + for (i = 0; i < z->count; i++) { + struct zip_entry *h = &z->entries[i]; + JZGlobalFileHeader *g = &h->header; + fwrite(g, 1, sizeof(JZGlobalFileHeader), z->out); + fwrite(h->filename, 1, g->fileNameLength, z->out); + fwrite(h->extra, 1, g->extraFieldLength, z->out); + fwrite(h->comment, 1, g->fileCommentLength, z->out); + } } end.centralDirectorySize = ftell(z->out) - end.centralDirectoryOffset; end.zipCommentLength = 0; @@ -668,10 +689,13 @@ void zip_close(zip* z) { if( z->out ) fclose(z->out); if( z->in ) fclose(z->in); // clean up - for(unsigned i = 0; i < z->count; ++i ) { - REALLOC(z->entries[i].filename, 0); - if(z->entries[i].extra) REALLOC(z->entries[i].extra, 0); - if(z->entries[i].comment) REALLOC(z->entries[i].comment, 0); + { + unsigned i; + for (i = 0; i < z->count; ++i) { + REALLOC(z->entries[i].filename, 0); + if (z->entries[i].extra) REALLOC(z->entries[i].extra, 0); + if (z->entries[i].comment) REALLOC(z->entries[i].comment, 0); + } } if(z->entries) REALLOC(z->entries, 0); zip zero = {0}; *z = zero; REALLOC(z, 0); @@ -690,7 +714,7 @@ typedef struct tar tar; tar *tar_open(const char *filename, const char *mode); - int tar_find(tar*, const char *entryname); // returns entry number; or <0 if not found. + unsigned int tar_find(tar*, const char *entryname); // returns entry number; or <0 if not found. unsigned tar_count(tar*); char* tar_name(tar*, unsigned index); unsigned tar_size(tar*, unsigned index); @@ -823,9 +847,12 @@ tar *tar_open(const char *filename, const char *mode) { return t; } -int tar_find(tar *t, const char *entryname) { - if( t->in ) for( int i = t->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) - if( 0 == strcmp(entryname, t->entries[i].filename)) return i; +unsigned int tar_find(tar *t, const char *entryname) { + if( t->in ) { + unsigned i; + for ( i = t->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + if (0 == strcmp(entryname, t->entries[i].filename)) return i; + } } return -1; } @@ -859,12 +886,17 @@ void *tar_extract(tar *t, unsigned index) { void tar_close(tar *t) { fclose(t->in); - for( int i = 0; i < t->count; ++i) { - REALLOC(t->entries[i].filename, 0); + { + unsigned i; + for ( i = 0; i < t->count; ++i ) { + REALLOC(t->entries[i].filename, 0); + } + } + { + tar zero = {0}; + *t = zero; + REALLOC(t, 0); } - tar zero = {0}; - *t = zero; - REALLOC(t, 0); } #ifdef TAR_DEMO @@ -872,7 +904,8 @@ int main( int argc, char **argv ) { if(argc <= 1) exit(printf("%s file.tar [file_to_view]\n", argv[0])); tar *t = tar_open(argv[1], "rb"); if( t ) { - for( int i = 0; i < tar_count(t); ++i ) { + unsigned i; + for( i = 0; i < tar_count(t); ++i ) { printf("%d) %s (%u bytes)\n", i+1, tar_name(t,i), tar_size(t,i)); char *data = tar_extract(t,i); if(argc>2) if(0==strcmp(argv[2],tar_name(t,i))) printf("%.*s\n", tar_size(t,i), data); @@ -1023,10 +1056,13 @@ pak *pak_open(const char *fname, const char *mode) { goto fail; } - for( unsigned i = 0; i < num_files; ++i ) { - pak_file *e = &p->entries[i]; - e->offset = ltoh32(e->offset); - e->size = ltoh32(e->size); + { + unsigned i; + for ( i = 0; i < num_files; ++i ) { + pak_file *e = &p->entries[i]; + e->offset = ltoh32(e->offset); + e->size = ltoh32(e->size); + } } if( mode[0] == 'a' ) { @@ -1114,17 +1150,22 @@ void pak_close(pak *p) { if(p->out) { // write toc uint32_t seek = 0 + 12, dirpos = (uint32_t)ftell(p->out), dirlen = p->count * 64; - for(unsigned i = 0; i < p->count; ++i) { - pak_file *e = &p->entries[i]; - // write name (truncated if needed), and trailing zeros - char zero[56] = {0}; - int namelen = strlen(e->name); - fwrite( e->name, 1, namelen >= 56 ? 55 : namelen, p->out ); - fwrite( zero, 1, namelen >= 56 ? 1 : 56 - namelen, p->out ); - // write offset + length pair - uint32_t pseek = htol32(seek); fwrite( &pseek, 1,4, p->out ); - uint32_t psize = htol32(e->size); fwrite( &psize, 1,4, p->out ); - seek += e->size; + { + unsigned i; + for ( i = 0; i < p->count; ++i ) { + pak_file *e = &p->entries[i]; + // write name (truncated if needed), and trailing zeros + char zero[56] = {0}; + int namelen = strlen(e->name); + fwrite(e->name, 1, namelen >= 56 ? 55 : namelen, p->out); + fwrite(zero, 1, namelen >= 56 ? 1 : 56 - namelen, p->out); + // write offset + length pair + uint32_t pseek = htol32(seek); + fwrite(&pseek, 1, 4, p->out); + uint32_t psize = htol32(e->size); + fwrite(&psize, 1, 4, p->out); + seek += e->size; + } } // patch header @@ -1139,8 +1180,11 @@ void pak_close(pak *p) { if(p->out) fclose(p->out); // clean up - for(unsigned i = 0; i < p->count; ++i) { - pak_file *e = &p->entries[i]; + { + unsigned i; + for ( i = 0; i < p->count; ++i ) { + pak_file *e = &p->entries[i]; + } } REALLOC(p->entries, 0); @@ -1152,7 +1196,8 @@ void pak_close(pak *p) { int pak_find(pak *p, const char *filename) { if( p->in ) { - for( int i = p->count; --i >= 0; ) { + unsigned i; + for( i = p->count; --i >= 0; ) { if(!strcmp(p->entries[i].name, filename)) return i; } } @@ -1216,7 +1261,8 @@ int main(int argc, char **argv) { printf("listing %s archive ...\n", fname); p = pak_open(fname, "rb"); if( p ) { - for( unsigned i = 0; i < pak_count(p); ++i ) { + unsigned i; + for( i = 0; i < pak_count(p); ++i ) { printf(" %d) @%08x %11u %s ", i+1, pak_offset(p,i), pak_size(p,i), pak_name(p,i)); void *data = pak_extract(p,i); printf("\r%c\n", data ? 'Y':'N'); @@ -1240,7 +1286,7 @@ int main(int argc, char **argv) { // - note: vfs_mount() order matters (the most recent the higher priority). void vfs_mount(const char *path); // zipfile or directory/with/trailing/slash/ -char* vfs_load(const char *filename, int *size); // must free() after use +char* vfs_load(const char *filename, unsigned int *size); // must free() after use // ----------------------------------------------------------------------------- @@ -1291,15 +1337,16 @@ void vfs_mount(const char *path) { dir_head->is_directory = is_directory; } -char *vfs_load(const char *filename, int *size) { // must free() after use +char *vfs_load(const char *filename, unsigned int *size) { // must free() after use char *data = NULL; - for(vfs_dir *dir = dir_head; dir && !data; dir = dir->next) { + vfs_dir *dir; + for( dir = dir_head; dir && !data; dir = dir->next ) { if( dir->is_directory ) { char buf[512]; snprintf(buf, sizeof(buf), "%s%s", dir->path, filename); data = vfs_read_file(buf, size); } else { - int index = zip_find(dir->archive, filename); + unsigned int index = zip_find(dir->archive, filename); data = zip_extract(dir->archive, index); if( size ) *size = zip_size(dir->archive, index); } @@ -1394,22 +1441,28 @@ int dir_yield(dir *d, const char *pathfile, char *name, int namelen) { #ifdef _WIN32 WIN32_FIND_DATAA fdata = { 0 }; snprintf(name, namelen, "%s/*", pathfile); - for( HANDLE h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; (ok = FindClose( h ), h = INVALID_HANDLE_VALUE, 1)) { - for( int next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { - if( fdata.cFileName[0] == '.' ) continue; - int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; - snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); - struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; - // add - dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; - d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); - d->entry[d->count-1] = de; + { + HANDLE h; + for( h = FindFirstFileA(name, &fdata ); h != INVALID_HANDLE_VALUE; (ok = FindClose( h ), h = INVALID_HANDLE_VALUE, 1) ) { + int next; + for( next = 1; next; next = FindNextFileA(h, &fdata) != 0 ) { + if( fdata.cFileName[0] == '.' ) continue; + int is_dir = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0; + snprintf(name, namelen, "%s/%s%s", pathfile, fdata.cFileName, is_dir ? "/" : ""); + struct stat st; if( !is_dir ) if(stat(name, &st) < 0) continue; + // add + dir_entry de = { STRDUP(name), is_dir ? 0 : st.st_size, is_dir }; + d->entry = (dir_entry*)REALLOC(d->entry, ++d->count * sizeof(dir_entry)); + d->entry[d->count-1] = de; + } } } #else snprintf(name, namelen, "%s/", pathfile); - for( DIR *dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1)) { - for( struct dirent *ep; ep = readdir(dir); ) { + DIR *dir; + for( dir = opendir(name); dir; ok = (closedir(dir), dir = 0, 1) ) { + struct dirent *ep; + while( (ep = readdir(dir)) ) { if( ep->d_name[0] == '.' ) continue; snprintf(name, namelen, "%s/%s", pathfile, ep->d_name); struct stat st; if( stat(name, &st) < 0 ) continue; @@ -1430,10 +1483,16 @@ dir *dir_open(const char *pathfile, const char *mode) { dir *d = (dir*)REALLOC(0, sizeof(dir)), zero = {0}; *d = zero; char *clean = STRDUP( pathfile ); - for( int i = 0; clean[i]; ++i ) if(clean[i] == '\\') clean[i] = '/'; - for( int len = strlen(clean); clean[--len] == '/'; ) clean[len] = '\0'; - char buffer[2048]; + { + int i; + for (i = 0; clean[i]; ++i) if (clean[i] == '\\') clean[i] = '/'; + } + { + size_t len; + for (len = strlen(clean); clean[--len] == '/';) clean[len] = '\0'; + } + dir_yield(d, clean, buffer, 2048); REALLOC(clean, 0); @@ -1441,7 +1500,8 @@ dir *dir_open(const char *pathfile, const char *mode) { } int dir_find(dir *d, const char *entryname) { - for( int i = d->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) + int i; + for( i = d->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) if( 0 == strcmp(entryname, d->entry[i].filename)) return i; } return -1; @@ -1466,7 +1526,8 @@ unsigned dir_file(dir *d, unsigned index) { void *dir_read(dir *d, unsigned index) { if( d && index < d->count ) { void *data = 0; - for( FILE *fp = fopen(d->entry[index].filename, "rb"); fp; fclose(fp), fp = 0) { + FILE *fp; + for( fp = fopen(d->entry[index].filename, "rb"); fp; fclose(fp), fp = 0 ) { size_t len = d->entry[index].size; data = REALLOC(0, len); if( data && fread(data, 1, len, fp) != len ) { @@ -1479,7 +1540,8 @@ void *dir_read(dir *d, unsigned index) { } void dir_close(dir *d) { - for( int i = 0; i < d->count; ++i) { + int i; + for( i = 0; i < d->count; ++i ) { REALLOC(d->entry[i].filename, 0); } dir zero = {0}; @@ -1491,7 +1553,8 @@ void dir_close(dir *d) { int main( int argc, char **argv ) { dir *d = dir_open(argc > 1 ? argv[1] : "./", "rb"); if( d ) { - for( int i = 0; i < dir_count(d); ++i ) { + int i; + for( i = 0; i < dir_count(d); ++i ) { if( dir_file(d,i) ) printf("%3d) %11d %s\n", i + 1, dir_size(d,i), dir_name(d,i)); else From 0b50b6887526cd61db5129cd22fd4e31e1e9945e Mon Sep 17 00:00:00 2001 From: Samuel Marks <807580+SamuelMarks@users.noreply.github.com> Date: Mon, 8 Nov 2021 14:20:29 -0500 Subject: [PATCH 2/2] [stdarc.c,src/{dir,pak,tar,zip}.c] `unsigned` => `unsigned int` --- src/dir.c | 18 +++++++++--------- src/pak.c | 20 ++++++++++---------- src/tar.c | 24 ++++++++++++------------ src/zip.c | 24 ++++++++++++------------ stdarc.c | 32 ++++++++++++++++---------------- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/dir.c b/src/dir.c index b6189cd..cfb67c0 100644 --- a/src/dir.c +++ b/src/dir.c @@ -10,10 +10,10 @@ dir *dir_open(const char *filename, const char *mode); // recursive 'r' int dir_find(dir*, const char *entryname); // returns entry number; or <0 if not found. unsigned dir_count(dir*); - char* dir_name(dir*, unsigned index); - unsigned dir_size(dir*, unsigned index); - unsigned dir_file(dir*, unsigned index); // dir_isfile? bool? - void* dir_read(dir*, unsigned index); // must free() after use + char* dir_name(dir*, unsigned int index); + unsigned int dir_size(dir*, unsigned int index); + unsigned int dir_file(dir*, unsigned int index); // dir_isfile? bool? + void* dir_read(dir*, unsigned int index); // must free() after use void dir_close(dir*); @@ -132,7 +132,7 @@ dir *dir_open(const char *pathfile, const char *mode) { } int dir_find(dir *d, const char *entryname) { - int i; + unsigned i; for( i = d->count; --i >= 0; ) { // in case of several copies, grab most recent file (last coincidence) if( 0 == strcmp(entryname, d->entry[i].filename)) return i; } @@ -143,15 +143,15 @@ unsigned dir_count(dir *d) { return d ? d->count : 0; } -char* dir_name(dir *d, unsigned index) { +char* dir_name(dir *d, unsigned int index) { return d && index < d->count ? d->entry[index].filename : 0; } -unsigned dir_size(dir *d, unsigned index) { +unsigned int dir_size(dir *d, unsigned int index) { return d && index < d->count ? (unsigned)d->entry[index].size : 0; } -unsigned dir_file(dir *d, unsigned index) { +unsigned int dir_file(dir *d, unsigned int index) { return d && index < d->count ? (unsigned)!d->entry[index].is_dir : 0; } @@ -173,7 +173,7 @@ void *dir_read(dir *d, unsigned index) { void dir_close(dir *d) { { - int i; + unsigned i; for( i = 0; i < d->count; ++i ) { REALLOC(d->entry[i].filename, 0); } diff --git a/src/pak.c b/src/pak.c index e3e16f2..74cc10b 100644 --- a/src/pak.c +++ b/src/pak.c @@ -25,15 +25,15 @@ pak* pak_open(const char *fname, const char *mode /*a,r,w*/); // (w)rite or (a)ppend modes only int pak_append_file(pak*, const char *filename, FILE *in); - int pak_append_data(pak*, const char *filename, const void *in, unsigned inlen); + int pak_append_data(pak*, const char *filename, const void *in, unsigned int inlen); // (r)ead only mode int pak_find(pak*,const char *fname); // return <0 if error; index otherwise. - unsigned pak_count(pak*); - unsigned pak_size(pak*,unsigned index); - unsigned pak_offset(pak*, unsigned index); - char *pak_name(pak*,unsigned index); - void *pak_extract(pak*, unsigned index); // must free() after use + unsigned int pak_count(pak*); + unsigned int pak_size(pak*,unsigned int index); + unsigned int pak_offset(pak*, unsigned int index); + char *pak_name(pak*,unsigned int index); + void *pak_extract(pak*, unsigned int index); // must free() after use void pak_close(pak*); @@ -95,7 +95,7 @@ typedef struct pak { FILE *in, *out; int dummy; pak_file *entries; - unsigned count; + unsigned int count; } pak; pak *pak_open(const char *fname, const char *mode) { @@ -189,7 +189,7 @@ fail:; return NULL; } -int pak_append_data(pak *p, const char *filename, const void *in, unsigned inlen) { +int pak_append_data(pak *p, const char *filename, const void *in, unsigned int inlen) { if(!p->out) return ERR(0, "read-only pak file"); // index meta @@ -277,7 +277,7 @@ void pak_close(pak *p) { int pak_find(pak *p, const char *filename) { if( p->in ) { { - int i; + unsigned i; for( i = p->count; --i >= 0; ) { if(!strcmp(p->entries[i].name, filename)) return i; } @@ -286,7 +286,7 @@ int pak_find(pak *p, const char *filename) { return -1; } -unsigned pak_count(pak *p) { +unsigned int pak_count(pak *p) { return p->in ? p->count : 0; } diff --git a/src/tar.c b/src/tar.c index 5ee79ed..6a80ce3 100644 --- a/src/tar.c +++ b/src/tar.c @@ -9,11 +9,11 @@ typedef struct tar tar; tar *tar_open(const char *filename, const char *mode); unsigned int tar_find(tar*, const char *entryname); // returns entry number; or <0 if not found. - unsigned tar_count(tar*); - char* tar_name(tar*, unsigned index); - unsigned tar_size(tar*, unsigned index); - unsigned tar_offset(tar*, unsigned index); - void* tar_extract(tar*, unsigned index); // must free() after use + unsigned int tar_count(tar*); + char* tar_name(tar*, unsigned int index); + unsigned tar_size(tar*, unsigned int index); + unsigned tar_offset(tar*, unsigned int index); + void* tar_extract(tar*, unsigned int index); // must free() after use void tar_close(tar *t); @@ -42,10 +42,10 @@ void tar_close(tar *t); struct tar { FILE *in; - unsigned count; + unsigned int count; struct tar_entry { char *filename; - unsigned size; + unsigned int size; size_t offset; } *entries; }; @@ -60,9 +60,9 @@ uint64_t tar__octal( const char *src, const char *eof ) { return sum; } -typedef int (*tar_callback)(const char *filename, unsigned inlen, size_t offset, void *userdata); +typedef int (*tar_callback)(const char *filename, unsigned int inlen, size_t offset, void *userdata); -int tar__push_entry(const char *filename, unsigned inlen, size_t offset, void *userdata) { +int tar__push_entry(const char *filename, unsigned int inlen, size_t offset, void *userdata) { tar *t = (tar *)userdata; unsigned index = t->count; @@ -151,7 +151,7 @@ unsigned int tar_find(tar *t, const char *entryname) { return -1; } -unsigned tar_count(tar *t) { +unsigned int tar_count(tar *t) { return t ? t->count : 0; } @@ -159,7 +159,7 @@ char* tar_name(tar *t, unsigned index) { return t && index < t->count ? t->entries[index].filename : 0; } -unsigned tar_size(tar *t, unsigned index) { +unsigned int tar_size(tar *t, unsigned int index) { return t && index < t->count ? t->entries[index].size : 0; } @@ -181,7 +181,7 @@ void *tar_extract(tar *t, unsigned index) { void tar_close(tar *t) { fclose(t->in); { - int i; + unsigned i; for( i = 0; i < t->count; ++i ) { REALLOC(t->entries[i].filename, 0); } diff --git a/src/zip.c b/src/zip.c index b814082..cb671e5 100644 --- a/src/zip.c +++ b/src/zip.c @@ -24,18 +24,18 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/); // only for (r)ead mode unsigned int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. - unsigned zip_count(zip*); - char* zip_name(zip*, unsigned index); - char* zip_modt(zip*, unsigned index); - unsigned zip_size(zip*, unsigned index); - unsigned zip_hash(zip*, unsigned index); - bool zip_file(zip*, unsigned index); // is_file? (dir if name ends with '/'; file otherwise) - bool zip_test(zip*, unsigned index); - unsigned zip_codec(zip*, unsigned index); - unsigned zip_offset(zip*, unsigned index); - void* zip_extract(zip*, unsigned index); // must free() after use - bool zip_extract_file(zip*, unsigned index, FILE *out); - unsigned zip_extract_data(zip*, unsigned index, void *out, unsigned outlen); + unsigned int zip_count(zip*); + char* zip_name(zip*, unsigned int index); + char* zip_modt(zip*, unsigned int index); + unsigned int zip_size(zip*, unsigned int index); + unsigned int zip_hash(zip*, unsigned int index); + bool zip_file(zip*, unsigned int index); // is_file? (dir if name ends with '/'; file otherwise) + bool zip_test(zip*, unsigned int index); + unsigned int zip_codec(zip*, unsigned int index); + unsigned int zip_offset(zip*, unsigned int index); + void* zip_extract(zip*, unsigned int index); // must free() after use + bool zip_extract_file(zip*, unsigned int index, FILE *out); + unsigned int zip_extract_data(zip*, unsigned int index, void *out, unsigned int outlen); void zip_close(zip*); diff --git a/stdarc.c b/stdarc.c index 6c9e5ad..3ae9a3f 100644 --- a/stdarc.c +++ b/stdarc.c @@ -37,22 +37,22 @@ typedef struct zip zip; zip* zip_open(const char *file, const char *mode /*r,w,a*/); // only for (w)rite or (a)ppend mode - bool zip_append_file(zip*, const char *entryname, FILE *in, unsigned compr_level); + bool zip_append_file(zip*, const char *entryname, FILE *in, unsigned int compr_level); // only for (r)ead mode unsigned int zip_find(zip*, const char *entryname); // convert entry to index. returns <0 if not found. - unsigned zip_count(zip*); - char* zip_name(zip*, unsigned index); - char* zip_modt(zip*, unsigned index); - unsigned zip_size(zip*, unsigned index); - unsigned zip_hash(zip*, unsigned index); - bool zip_file(zip*, unsigned index); // is_file? (dir if name ends with '/'; file otherwise) - bool zip_test(zip*, unsigned index); - unsigned zip_codec(zip*, unsigned index); - unsigned zip_offset(zip*, unsigned index); - void* zip_extract(zip*, unsigned index); // must free() after use - bool zip_extract_file(zip*, unsigned index, FILE *out); - unsigned zip_extract_data(zip*, unsigned index, void *out, unsigned outlen); + unsigned int zip_count(zip*); + char* zip_name(zip*, unsigned int index); + char* zip_modt(zip*, unsigned int index); + unsigned int zip_size(zip*, unsigned int index); + unsigned int zip_hash(zip*, unsigned int index); + bool zip_file(zip*, unsigned int index); // is_file? (dir if name ends with '/'; file otherwise) + bool zip_test(zip*, unsigned int index); + unsigned int zip_codec(zip*, unsigned int index); + unsigned int zip_offset(zip*, unsigned int index); + void* zip_extract(zip*, unsigned int index); // must free() after use + bool zip_extract_file(zip*, unsigned int index, FILE *out); + unsigned int zip_extract_data(zip*, unsigned int index, void *out, unsigned int outlen); void zip_close(zip*); @@ -857,7 +857,7 @@ unsigned int tar_find(tar *t, const char *entryname) { return -1; } -unsigned tar_count(tar *t) { +unsigned int tar_count(tar *t) { return t ? t->count : 0; } @@ -1204,11 +1204,11 @@ int pak_find(pak *p, const char *filename) { return -1; } -unsigned pak_count(pak *p) { +unsigned int pak_count(pak *p) { return p->in ? p->count : 0; } -unsigned pak_offset(pak *p, unsigned index) { +unsigned int pak_offset(pak *p, unsigned index) { return p->in && index < p->count ? p->entries[index].offset : 0; }