On 10/7/12 7:55 AM, Akira TAGOH wrote:
Not yet carefully having a look at the patch, that would be nice if you can make some separate patches by purpose or fixes rather than sending a big patch. other than that, adding fc_ function prefix doesn't match to current policy. fc_open should be FcOpen or something like that say.
I am not sure how I can break up this patch since on their own the changes are meaningless. There aren't fixes there, it's all pretty much introduction of a thin portability layer.
In any case, I've attached a revised patch. This one implements auto generation of fontconfig.def using cmake, and changes fc_... portability wrappers to CamelCase.
Thank you, Pavel.
From 09cfd2912fd31aed80bd02c782998e18beab89ca Mon Sep 17 00:00:00 2001 From: Pavel Koshevoy <pkoshevoy@xxxxxxxxx> Date: Sun, 7 Oct 2012 23:20:33 -0600 Subject: [PATCH] Add a thin portability layer for msvcport and cmake project. Visual Studio does not support debugging code compiled with gcc. With this cmake project one can generate a Visual Studio solution for fontconfig and compile it Debug/Release/etc... win32 or x64 Because Visual Studio doesn't provide dirent.h a wrapper implementation that mimics dirent API is provided in msvcport. Since standard io libc functions that accept char * for filepath parameter do not support UTF-8 encoded string msvcport provides wrappers that expect UTF-8 strings and internally convert them to UTF-16 strings and call corresponding unicode win32 functions. --- CMakeLists.txt | 526 +++++++++++++++++++++++++++++++++++++++++++ config-fixups.h | 18 ++ msvcport/dirent.h | 8 + msvcport/inttypes.h | 305 +++++++++++++++++++++++++ msvcport/msvcport.h | 21 ++ msvcport/msvcport_private.c | 306 +++++++++++++++++++++++++ msvcport/msvcport_private.h | 59 +++++ msvcport/stdint.h | 247 ++++++++++++++++++++ src/fcatomic.c | 36 ++-- src/fccache.c | 42 ++-- src/fccfg.c | 2 +- src/fcdir.c | 6 +- src/fcformat.c | 4 + src/fcint.h | 2 + src/fcstat.c | 43 +++- src/fcxml.c | 17 +- 16 files changed, 1581 insertions(+), 61 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 msvcport/dirent.h create mode 100644 msvcport/fcftalias.h create mode 100644 msvcport/fcftaliastail.h create mode 100644 msvcport/inttypes.h create mode 100644 msvcport/msvcport.h create mode 100644 msvcport/msvcport_private.c create mode 100644 msvcport/msvcport_private.h create mode 100644 msvcport/stdint.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..92043b7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,526 @@ +cmake_minimum_required(VERSION 2.8.0) + +project(fontconfig) + +include_directories(AFTER + ${CMAKE_CURRENT_SOURCE_DIR} + src + ) + + +set(FONTCONFIG_DEF "${PROJECT_BINARY_DIR}/src/fontconfig.def") +set_source_files_properties("${FONTCONFIG_DEF}" PROPERTIES GENERATED true) + +file(STRINGS fontconfig/fontconfig.h READ_FONTCONFIG_H REGEX "^Fc[^ ]* *\\(") +file(STRINGS src/fcdeprecate.h READ_FCDEPRECATE_H REGEX "^Fc[^ ]* *\\(") +file(STRINGS fontconfig/fcprivate.h READ_FCPRIVATE_H REGEX "^Fc[^ ]* *\\(") +file(STRINGS fontconfig/fcfreetype.h READ_FCFREETYPE_H REGEX "^Fc[^ ]* *\\(") + +file(WRITE "${FONTCONFIG_DEF}" "EXPORTS\n") +foreach(line ${READ_FONTCONFIG_H} ${READ_FCDEPRECATE_H} ${READ_FCPRIVATE_H} ${READ_FCFREETYPE_H}) + string(REGEX REPLACE + " *\\(.*$" + "" + FONTCONFIG_EXPORT + "${line}" + ) + file(APPEND "${FONTCONFIG_DEF}" " ${FONTCONFIG_EXPORT}\n") +endforeach(line) +file(APPEND "${FONTCONFIG_DEF}" "LIBRARY fontconfig_shared.dll\n") +file(APPEND "${FONTCONFIG_DEF}" "VERSION 7.2\n") + + +set(CASEFOLDING_TXT "${PROJECT_SOURCE_DIR}/fc-case/CaseFolding.txt") +set(FCCASE_TMPL_H "${PROJECT_SOURCE_DIR}/fc-case/fccase.tmpl.h") +set(FCCASE_H "${PROJECT_SOURCE_DIR}/fc-case/fccase.h") +set_source_files_properties("${FCCASE_H}" PROPERTIES GENERATED true) + +if (MINGW OR MSYS) + string(REPLACE "/" "\\\\" NATIVE_CASEFOLDING_TXT "${CASEFOLDING_TXT}") + string(REPLACE "/" "\\\\" NATIVE_FCCASE_TMPL_H "${FCCASE_TMPL_H}") + string(REPLACE "/" "\\\\" NATIVE_FCCASE_H "${FCCASE_H}") +else (MINGW OR MSYS) + file(TO_NATIVE_PATH "${CASEFOLDING_TXT}" NATIVE_CASEFOLDING_TXT) + file(TO_NATIVE_PATH "${FCCASE_TMPL_H}" NATIVE_FCCASE_TMPL_H) + file(TO_NATIVE_PATH "${FCCASE_H}" NATIVE_FCCASE_H) +endif (MINGW OR MSYS) + +add_custom_command(OUTPUT "${FCCASE_H}" + COMMAND fc-case + ARGS + "${NATIVE_CASEFOLDING_TXT}" < "${NATIVE_FCCASE_TMPL_H}" > "${NATIVE_FCCASE_H}" + DEPENDS + fc-case + ) + +set(ZAPFDINGBATS_TXT "${PROJECT_SOURCE_DIR}/fc-glyphname/zapfdingbats.txt") +set(FCGLYPHNAME_TMPL_H "${PROJECT_SOURCE_DIR}/fc-glyphname/fcglyphname.tmpl.h") +set(FCGLYPHNAME_H "${PROJECT_SOURCE_DIR}/fc-glyphname/fcglyphname.h") +set_source_files_properties("${FCGLYPHNAME_H}" PROPERTIES GENERATED true) + +if (MINGW OR MSYS) + string(REPLACE "/" "\\\\" NATIVE_ZAPFDINGBATS_TXT "${ZAPFDINGBATS_TXT}") + string(REPLACE "/" "\\\\" NATIVE_FCGLYPHNAME_TMPL_H "${FCGLYPHNAME_TMPL_H}") + string(REPLACE "/" "\\\\" NATIVE_FCGLYPHNAME_H "${FCGLYPHNAME_H}") +else (MINGW OR MSYS) + file(TO_NATIVE_PATH "${ZAPFDINGBATS_TXT}" NATIVE_ZAPFDINGBATS_TXT) + file(TO_NATIVE_PATH "${FCGLYPHNAME_TMPL_H}" NATIVE_FCGLYPHNAME_TMPL_H) + file(TO_NATIVE_PATH "${FCGLYPHNAME_H}" NATIVE_FCGLYPHNAME_H) +endif (MINGW OR MSYS) + +add_custom_command(OUTPUT "${FCGLYPHNAME_H}" + COMMAND fc-glyphname + ARGS + "${NATIVE_ZAPFDINGBATS_TXT}" < "${NATIVE_FCGLYPHNAME_TMPL_H}" > "${NATIVE_FCGLYPHNAME_H}" + DEPENDS + fc-glyphname + ) + + +set(FCLANG_ORTH + aa.orth + ab.orth + af.orth + ak.orth + am.orth + an.orth + ar.orth + as.orth + ast.orth + av.orth + ay.orth + az_az.orth + az_ir.orth + ba.orth + be.orth + ber_dz.orth + ber_ma.orth + bg.orth + bh.orth + bho.orth + bi.orth + bin.orth + bm.orth + bn.orth + bo.orth + br.orth + brx.orth + bs.orth + bua.orth + byn.orth + ca.orth + ce.orth + ch.orth + chm.orth + chr.orth + co.orth + crh.orth + cs.orth + csb.orth + cu.orth + cv.orth + cy.orth + da.orth + de.orth + doi.orth + dv.orth + dz.orth + ee.orth + el.orth + en.orth + eo.orth + es.orth + et.orth + eu.orth + fa.orth + fat.orth + ff.orth + fi.orth + fil.orth + fj.orth + fo.orth + fr.orth + fur.orth + fy.orth + ga.orth + gd.orth + gez.orth + gl.orth + gn.orth + gu.orth + gv.orth + ha.orth + haw.orth + he.orth + hi.orth + hne.orth + ho.orth + hr.orth + hsb.orth + ht.orth + hu.orth + hy.orth + hz.orth + ia.orth + id.orth + ie.orth + ig.orth + ii.orth + ik.orth + io.orth + is.orth + it.orth + iu.orth + ja.orth + jv.orth + ka.orth + kaa.orth + kab.orth + ki.orth + kj.orth + kk.orth + kl.orth + km.orth + kn.orth + ko.orth + kok.orth + kr.orth + ks.orth + ku_am.orth + ku_iq.orth + ku_ir.orth + ku_tr.orth + kum.orth + kv.orth + kw.orth + kwm.orth + ky.orth + la.orth + lah.orth + lb.orth + lez.orth + lg.orth + li.orth + ln.orth + lo.orth + lt.orth + lv.orth + mai.orth + mg.orth + mh.orth + mi.orth + mk.orth + ml.orth + mn_cn.orth + mn_mn.orth + mni.orth + mo.orth + mr.orth + ms.orth + mt.orth + my.orth + na.orth + nb.orth + nds.orth + ne.orth + ng.orth + nl.orth + nn.orth + no.orth + nqo.orth + nr.orth + nso.orth + nv.orth + ny.orth + oc.orth + om.orth + or.orth + os.orth + ota.orth + pa.orth + pa_pk.orth + pap_an.orth + pap_aw.orth + pes.orth + pl.orth + prs.orth + ps_af.orth + ps_pk.orth + pt.orth + qu.orth + rm.orth + rn.orth + ro.orth + ru.orth + rw.orth + sa.orth + sah.orth + sat.orth + sc.orth + sco.orth + sd.orth + se.orth + sel.orth + sg.orth + sh.orth + shs.orth + si.orth + sid.orth + sk.orth + sl.orth + sm.orth + sma.orth + smj.orth + smn.orth + sms.orth + sn.orth + so.orth + sq.orth + sr.orth + ss.orth + st.orth + su.orth + sv.orth + sw.orth + syr.orth + ta.orth + te.orth + tg.orth + th.orth + ti_er.orth + ti_et.orth + tig.orth + tk.orth + tl.orth + tn.orth + to.orth + tr.orth + ts.orth + tt.orth + tw.orth + ty.orth + tyv.orth + ug.orth + uk.orth + ur.orth + uz.orth + ve.orth + vi.orth + vo.orth + vot.orth + wa.orth + wal.orth + wen.orth + wo.orth + xh.orth + yap.orth + yi.orth + yo.orth + za.orth + zh_cn.orth + zh_hk.orth + zh_mo.orth + zh_sg.orth + zh_tw.orth + zu.orth +) + + +set(FCLANG_DIR "${PROJECT_SOURCE_DIR}/fc-lang") +set(FCLANG_TMPL_H "${PROJECT_SOURCE_DIR}/fc-lang/fclang.tmpl.h") +set(FCLANG_H "${PROJECT_SOURCE_DIR}/fc-lang/fclang.h") +set_source_files_properties("${FCLANG_H}" PROPERTIES GENERATED true) + +if (MINGW OR MSYS) + string(REPLACE "/" "\\\\" NATIVE_FCLANG_DIR "${FCLANG_DIR}") + string(REPLACE "/" "\\\\" NATIVE_FCLANG_TMPL_H "${FCLANG_TMPL_H}") + string(REPLACE "/" "\\\\" NATIVE_FCLANG_H "${FCLANG_H}") +else (MINGW OR MSYS) + file(TO_NATIVE_PATH "${FCLANG_DIR}" NATIVE_FCLANG_DIR) + file(TO_NATIVE_PATH "${FCLANG_TMPL_H}" NATIVE_FCLANG_TMPL_H) + file(TO_NATIVE_PATH "${FCLANG_H}" NATIVE_FCLANG_H) +endif (MINGW OR MSYS) + +add_custom_command(OUTPUT "${FCLANG_H}" + COMMAND fc-lang + ARGS + -d "${NATIVE_FCLANG_DIR}" ${FCLANG_ORTH} < "${NATIVE_FCLANG_TMPL_H}" > "${NATIVE_FCLANG_H}" + DEPENDS + fc-lang "${FCCASE_H}" + ) + + +add_custom_target("autogenerate" ALL + DEPENDS + "${FCCASE_H}" + "${FCGLYPHNAME_H}" + "${FCLANG_H}" + ) + +add_executable(fc-case + fc-case/fc-case.c + fc-case/fccase.tmpl.h + fc-case/CaseFolding.txt + ) + + +add_executable(fc-lang + "${FCCASE_H}" + fc-lang/fc-lang.c + fc-lang/fclang.tmpl.h + fc-lang/iso-3166.txt + fc-lang/iso639-1 + fc-lang/iso639-2 + ) + +add_executable(fc-glyphname + fc-glyphname/fc-glyphname.c + fc-glyphname/fcglyphname.tmpl.h + ) + +if (WIN32) + ADD_DEFINITIONS(-D_USE_MATH_DEFINES) + ADD_DEFINITIONS(-DNOMINMAX) + ADD_DEFINITIONS(-DFC_CACHEDIR="WINDOWSTEMPDIR_FONTCONFIG_CACHE") + ADD_DEFINITIONS(-DHAVE_CONFIG_H) + + OPTION(LINKING_TO_STATIC_EXPAT_LIB "Check this if linking to static expat library" false) + if (LINKING_TO_STATIC_EXPAT_LIB) + ADD_DEFINITIONS(-DXML_STATIC=1) + endif(LINKING_TO_STATIC_EXPAT_LIB) + + include_directories(AFTER + msvcport + ) +endif (WIN32) + + +set(FREETYPE_DIR "$ENV{FREETYPE_DIR}" + CACHE PATH "root path for freetype lib/ and include/ folders" + ) +find_path(FREETYPE_INCLUDE_DIR + ft2build.h freetype2/freetype/freetype.h + PATHS ${FREETYPE_DIR}/include + ) +find_library(FREETYPE_LIBRARY + freetype libfreetype + PATHS ${FREETYPE_DIR}/lib + DOC "freetype library" + ) +if (FREETYPE_INCLUDE_DIR) + include_directories(AFTER ${FREETYPE_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIR}/freetype2) +endif (FREETYPE_INCLUDE_DIR) + + +set(EXPAT_DIR "$ENV{EXPAT_DIR}" + CACHE PATH "root path for expat lib/ and include/ folders" + ) +find_path(EXPAT_INCLUDE_DIR + expat.h + PATHS ${EXPAT_DIR}/include + ) +find_library(EXPAT_LIBRARY + expat libexpat + PATHS ${EXPAT_DIR}/lib + DOC "expat library" + ) +if (EXPAT_INCLUDE_DIR) + include_directories(AFTER ${EXPAT_INCLUDE_DIR}) +endif (EXPAT_INCLUDE_DIR) + + +set(ICONV_DIR "$ENV{ICONV_DIR}" + CACHE PATH "root path for iconv lib/ and include/ folders" + ) +find_path(ICONV_INCLUDE_DIR + iconv.h + PATHS ${ICONV_DIR}/include + ) +find_library(ICONV_LIBRARY + iconv libiconv + PATHS ${ICONV_DIR}/lib + DOC "iconv library" + ) +if (ICONV_INCLUDE_DIR) + include_directories(AFTER ${ICONV_INCLUDE_DIR}) +endif (ICONV_INCLUDE_DIR) + + +set(project_sources + "${FCCASE_H}" + "${FCLANG_H}" + "${FCGLYPHNAME_H}" + src/fcarch.h + src/fcatomic.c + src/fcblanks.c + src/fccache.c + src/fccfg.c + src/fccharset.c + src/fcdbg.c + src/fcdefault.c + src/fcdir.c + src/fcformat.c + src/fcfreetype.c + src/fcfs.c + src/fcinit.c + src/fclang.c + src/fclist.c + src/fcmatch.c + src/fcmatrix.c + src/fcname.c + src/fcpat.c + src/fcserialize.c + src/fcstat.c + src/fcstr.c + src/fcxml.c + src/ftglue.h + src/ftglue.c + ) + +if (WIN32) + set(project_sources + ${project_sources} + msvcport/config.h + msvcport/dirent.h + msvcport/fcalias.h + msvcport/fcaliastail.h + msvcport/fcftalias.h + msvcport/fcftaliastail.h + msvcport/inttypes.h + msvcport/stdint.h + msvcport/msvcport.h + msvcport/msvcport_private.h + msvcport/msvcport_private.c + ) + find_library(LIBGCC_LIBRARY libgcc PATHS ${FFMPEG_LIBS_PATH} DOC "mingw libgcc library") +endif (WIN32) + +add_library(fontconfig_static STATIC + ${project_sources} + ) +add_dependencies(fontconfig_static "autogenerate") + +add_library(fontconfig_shared SHARED + ${project_sources} + ${FONTCONFIG_DEF} + ) +add_dependencies(fontconfig_shared "autogenerate") + + +set(THIRD_PARTY_LIBS ${FREETYPE_LIBRARY} ${EXPAT_LIBRARY} ${ICONV_LIBRARY}) +if (WIN32) + if (LIBGCC_LIBRARY) + set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} ${LIBGCC_LIBRARY}) + endif (LIBGCC_LIBRARY) +endif (WIN32) +target_link_libraries(fontconfig_shared ${THIRD_PARTY_LIBS}) + + +install(TARGETS fontconfig_static fontconfig_shared DESTINATION lib) +install(FILES + fontconfig/fontconfig.h + fontconfig/fcfreetype.h + fontconfig/fcprivate.h + + DESTINATION + include/fontconfig) diff --git a/config-fixups.h b/config-fixups.h index 93ebf5b..87e9855 100644 --- a/config-fixups.h +++ b/config-fixups.h @@ -38,3 +38,21 @@ # define ALIGNOF_DOUBLE 4 # endif #endif + +/* a very thin portability layer */ +#if defined(_WIN32) && !defined(__MINGW32__) +#include "msvcport.h" +#else +#define FcOpendir(x) opendir(x) +#define FcReaddir(x) readdir(x) +#define FcClosedir(x) closedir(x) + +#define FcMkdir(x, y) mkdir(x, y) +#define FcRmdir(x) rmdir(x) + +#define FcAccess(x, y) access(x, y) +#define FcChmod(x, y) chmod(x, y) +#define FcUnlink(x) unlink(x) +#define FcOpen(x, y, ...) open(x, y, __VA_ARGS__) + +#endif diff --git a/msvcport/dirent.h b/msvcport/dirent.h new file mode 100644 index 0000000..b045938 --- /dev/null +++ b/msvcport/dirent.h @@ -0,0 +1,8 @@ +/* -*- Mode: c++; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef FONTCONFIG_DIRENT_H_ +#define FONTCONFIG_DIRENT_H_ + +#include "msvcport.h" + +#endif /* FONTCONFIG_DIRENT_H_ */ diff --git a/msvcport/fcftalias.h b/msvcport/fcftalias.h new file mode 100644 index 0000000..e69de29 diff --git a/msvcport/fcftaliastail.h b/msvcport/fcftaliastail.h new file mode 100644 index 0000000..e69de29 diff --git a/msvcport/inttypes.h b/msvcport/inttypes.h new file mode 100644 index 0000000..4b3828a --- /dev/null +++ b/msvcport/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/msvcport/msvcport.h b/msvcport/msvcport.h new file mode 100644 index 0000000..0ff6bf8 --- /dev/null +++ b/msvcport/msvcport.h @@ -0,0 +1,21 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef FONTCONFIG_MSVCPORT_H_ +#define FONTCONFIG_MSVCPORT_H_ + +#include "msvcport_private.h" + +#define FcOpendir(x) fc_msvcport_opendir(x) +#define FcReaddir(x) fc_msvcport_readdir(x) +#define FcClosedir(x) fc_msvcport_closedir(x) + +#define FcMkdir(x, y) fc_msvcport_mkdir(x, y) +#define FcRmdir(x) fc_msvcport_rmdir(x) + +#define FcAccess(x, y) fc_msvcport_access(x, y) +#define FcChmod(x, y) fc_msvcport_chmod(x, y) +#define FcUnlink(x) fc_msvcport_unlink(x) +#define FcOpen(x, y, ...) fc_msvcport_open(x, y, __VA_ARGS__) + + +#endif /* FONTCONFIG_MSVCPORT_H_ */ diff --git a/msvcport/msvcport_private.c b/msvcport/msvcport_private.c new file mode 100644 index 0000000..8bd8827 --- /dev/null +++ b/msvcport/msvcport_private.c @@ -0,0 +1,306 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +#if defined(_WIN32) + +#ifndef __STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif + +#include <windows.h> +#include <io.h> +#include <winnls.h> +#include <wchar.h> +#include <share.h> + +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "msvcport_private.h" + +wchar_t * +fc_utf8_to_utf16(const char * cstr) +{ + int sz = MultiByteToWideChar(CP_UTF8, 0, cstr, -1, NULL, 0); + wchar_t * wstr = (wchar_t *)malloc(sz * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, cstr, -1, wstr, sz); + return wstr; +} + +char * +fc_utf16_to_utf8(const wchar_t * wstr) +{ + int sz = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + char * cstr = (char *)malloc(sz); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, cstr, sz, NULL, NULL); + return cstr; +} + + +struct TDir +{ + struct dirent dirent_; + intptr_t handle_; + struct _wfinddata64_t dfound_; + int nfound_; + wchar_t * wquery_; +}; + +static void +TDirInit(struct TDir * d) +{ + memset(d, 0, sizeof(struct TDir)); +} + +static int +TDirClose(struct TDir * d) +{ + if (d->handle_) + { + int err = _findclose(d->handle_); + memset(&d->dirent_, 0, sizeof(d->dirent_)); + d->nfound_ = 0; + free(d->wquery_); + d->wquery_ = NULL; + return err; + } + + return 0; +} + +static int +TDirOpen(struct TDir * d, const char * path) +{ + size_t pathLen = strlen(path); + size_t queryLen = pathLen; + + char * query = (char *)malloc(pathLen + 3); + memcpy(query, path, queryLen); + + if (!pathLen || !strchr("\\/", path[pathLen - 1])) + { + query[queryLen++] = '/'; + } + + query[queryLen++] = '*'; + query[queryLen] = 0; + + TDirClose(d); + d->wquery_ = fc_utf8_to_utf16(query); + free(query); + query = NULL; + + if (!d->wquery_) + { + return 0; + } + + d->handle_ = _wfindfirst64(d->wquery_, &d->dfound_); + if (d->handle_) + { + return 1; + } + + return 0; +} + +static void +TDirLoad(struct TDir * d) +{ + static const size_t nameMax = sizeof(d->dirent_.d_name); + char * name = fc_utf16_to_utf8(d->dfound_.name); + size_t nameLen = strlen(name); + size_t copyLen = nameLen < nameMax ? nameLen : nameMax; + strncpy_s(d->dirent_.d_name, nameMax, name, copyLen); + free(name); +} + +static int +TDirNext(struct TDir * d) +{ + if (!d->handle_ || d->nfound_ < 0) + { + return 0; + } + + TDirLoad(d); + + if (_wfindnext64(d->handle_, &d->dfound_) == -1) + { + d->nfound_ = -1; + } + else + { + d->nfound_ ++; + } + + return 1; +} + + +void * +fc_msvcport_opendir(const char * path) +{ + struct TDir * dir = (struct TDir *)malloc(sizeof(struct TDir)); + TDirInit(dir); + + if (TDirOpen(dir, path)) + { + return dir; + } + + TDirClose(dir); + free(dir); + return NULL; +} + +int +fc_msvcport_closedir(void * priv) +{ + struct TDir * dir = (struct TDir *)priv; + if (!dir) + { + return -1; + } + + TDirClose(dir); + free(dir); + return 0; +} + +struct dirent * +fc_msvcport_readdir(void * priv) +{ + struct TDir * dir = (struct TDir *)priv; + if (dir && TDirNext(dir)) + { + return &(dir->dirent_); + } + + return NULL; +} + +int +fc_msvcport_mkdir(const char * path, int mode) +{ + wchar_t * tmp = fc_utf8_to_utf16(path); + int r = _wmkdir(tmp); + free(tmp); + return r; +} + +int +fc_msvcport_rmdir(const char * path) +{ + wchar_t * tmp = fc_utf8_to_utf16(path); + int r = _wrmdir(tmp); + free(tmp); + return r; +} + +int +fc_msvcport_access(const char * path, int perms) +{ + /* X_OK (01) permission causes fatal error in win32 _access(..), + therefore it must be excluded from the permission bitmask: */ + int wperms = perms & ~1; + + wchar_t * tmp = fc_utf8_to_utf16(path); + int r = _waccess(tmp, wperms); + free(tmp); + return r; +} + +int +fc_msvcport_chmod(const char * path, int unixPerms) +{ + wchar_t * tmp = fc_utf8_to_utf16(path); + int permissions = 0; + int ret = 0; + + if (unixPerms & 0444) + { + permissions |= _S_IREAD; + } + + if (unixPerms & 0222) + { + permissions |= _S_IWRITE; + } + + ret = _wchmod(tmp, permissions); + free(tmp); + return ret; +} + +int +fc_msvcport_rename(const char * fnOld, const char * fnNew) +{ + wchar_t * wold = fc_utf8_to_utf16(fnOld); + wchar_t * wnew = fc_utf8_to_utf16(fnNew); + + int ret = _wrename(wold, wnew); + + free(wold); + free(wnew); + return ret; +} + +int +fc_msvcport_unlink(const char * path) +{ + wchar_t * tmp = fc_utf8_to_utf16(path); + int r = _wunlink(tmp); + free(tmp); + return r; +} + +int +fc_msvcport_open(const char * filenameUtf8, int accessMode, ...) +{ + int waccessMode = accessMode | O_BINARY; + + wchar_t * wname = fc_utf8_to_utf16(filenameUtf8); + int fd = -1; + int sh = accessMode & (_O_RDWR | _O_WRONLY) ? _SH_DENYWR : _SH_DENYNO; + int permissions = _S_IREAD; + errno_t err = 0; + + if ((accessMode & _O_CREAT) != 0) + { + int unixPerms = 0644; + va_list ap; + va_start(ap, accessMode); + unixPerms = va_arg(ap, int); + + permissions = 0; + if (unixPerms & 0444) + { + permissions |= _S_IREAD; + } + + if (unixPerms & 0222) + { + permissions |= _S_IWRITE; + } + + if (unixPerms & 0111) + { + permissions |= _S_IEXEC; + } + + va_end(ap); + } + + err = _wsopen_s(&fd, wname, waccessMode, sh, permissions); + free(wname); + + return fd; +} + + +#endif /* _WIN32 */ diff --git a/msvcport/msvcport_private.h b/msvcport/msvcport_private.h new file mode 100644 index 0000000..a390e32 --- /dev/null +++ b/msvcport/msvcport_private.h @@ -0,0 +1,59 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + +#ifndef FONTCONFIG_MSVCPORT_PRIVATE_H_ +#define FONTCONFIG_MSVCPORT_PRIVATE_H_ + +#include <wchar.h> + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + + wchar_t * fc_utf8_to_utf16(const char * cstr); + char * fc_utf16_to_utf8(const wchar_t * wstr); + + /* NOTE: + all char * strings passed to or returned from these + fc_msvcport_... functions are UTF-8 encoded + */ + + typedef void * DIR; + + /* + this structure is layed out same as in mingw/include/dirent.h + for binary compatibility with code built with mingw compiler + */ + struct dirent + { + long int d_ino; /* always zero */ + unsigned short int d_reclen; /* always zero */ + unsigned short int d_namlen; /* name length */ + char d_name[260]; /* name[FILENAME_MAX] */ + }; + + extern void * fc_msvcport_opendir(const char * path); + extern struct dirent * fc_msvcport_readdir(void * priv); + extern int fc_msvcport_closedir(void * priv); + + extern int fc_msvcport_mkdir(const char * path, int mode); + extern int fc_msvcport_rmdir(const char * path); + + enum + { + F_OK = 0, /* Existence only */ + W_OK = 2, /* Write permission */ + R_OK = 4 /* Read permission */ + }; + + extern int fc_msvcport_access(const char * path, int perms); + extern int fc_msvcport_chmod(const char * path, int mode); + extern int fc_msvcport_rename(const char * fnOld, const char * fnNew); + extern int fc_msvcport_unlink(const char * path); + extern int fc_msvcport_open(const char * fn, int oflag, ...); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + + +#endif /* FONTCONFIG_MSVCPORT_PRIVATE_H_ */ diff --git a/msvcport/stdint.h b/msvcport/stdint.h new file mode 100644 index 0000000..d02608a --- /dev/null +++ b/msvcport/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include <limits.h> + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include <wchar.h> +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/src/fcatomic.c b/src/fcatomic.c index 350744a..43c5c70 100644 --- a/src/fcatomic.c +++ b/src/fcatomic.c @@ -51,14 +51,12 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#ifdef HAVE_UNISTD_H #include <unistd.h> +#endif #include <stdlib.h> #include <time.h> -#ifdef _WIN32 -#define mkdir(path,mode) _mkdir(path) -#endif - #define NEW_NAME ".NEW" #define LCK_NAME ".LCK" #define TMP_NAME ".TMP-XXXXXX" @@ -116,19 +114,19 @@ FcAtomicLock (FcAtomic *atomic) if (!f) { close (fd); - unlink ((char *) atomic->tmp); + FcUnlink ((char *) atomic->tmp); return FcFalse; } ret = fprintf (f, "%ld\n", (long)getpid()); if (ret <= 0) { fclose (f); - unlink ((char *) atomic->tmp); + FcUnlink ((char *) atomic->tmp); return FcFalse; } if (fclose (f) == EOF) { - unlink ((char *) atomic->tmp); + FcUnlink ((char *) atomic->tmp); return FcFalse; } ret = link ((char *) atomic->tmp, (char *) atomic->lck); @@ -137,12 +135,12 @@ FcAtomicLock (FcAtomic *atomic) /* the filesystem where atomic->lck points to may not supports * the hard link. so better try to fallback */ - ret = mkdir ((char *) atomic->lck, 0600); + ret = FcMkdir ((char *) atomic->lck, 0600); no_link = FcTrue; } - (void) unlink ((char *) atomic->tmp); + (void) FcUnlink ((char *) atomic->tmp); #else - ret = mkdir ((char *) atomic->lck, 0600); + ret = FcMkdir ((char *) atomic->lck, 0600); #endif if (ret < 0) { @@ -160,23 +158,23 @@ FcAtomicLock (FcAtomic *atomic) #ifdef HAVE_LINK if (no_link) { - if (rmdir ((char *) atomic->lck) == 0) + if (FcRmdir ((char *) atomic->lck) == 0) return FcAtomicLock (atomic); } else { - if (unlink ((char *) atomic->lck) == 0) + if (FcUnlink ((char *) atomic->lck) == 0) return FcAtomicLock (atomic); } #else - if (rmdir ((char *) atomic->lck) == 0) + if (FcRmdir ((char *) atomic->lck) == 0) return FcAtomicLock (atomic); #endif } } return FcFalse; } - (void) unlink ((char *) atomic->new); + (void) FcUnlink ((char *) atomic->new); return FcTrue; } @@ -196,7 +194,7 @@ FcBool FcAtomicReplaceOrig (FcAtomic *atomic) { #ifdef _WIN32 - unlink ((const char *) atomic->file); + FcUnlink ((const char *) atomic->file); #endif if (rename ((char *) atomic->new, (char *) atomic->file) < 0) return FcFalse; @@ -206,17 +204,17 @@ FcAtomicReplaceOrig (FcAtomic *atomic) void FcAtomicDeleteNew (FcAtomic *atomic) { - unlink ((char *) atomic->new); + FcUnlink ((char *) atomic->new); } void FcAtomicUnlock (FcAtomic *atomic) { #ifdef HAVE_LINK - if (unlink ((char *) atomic->lck) == -1) - rmdir ((char *) atomic->lck); + if (FcUnlink ((char *) atomic->lck) == -1) + FcRmdir ((char *) atomic->lck); #else - rmdir ((char *) atomic->lck); + FcRmdir ((char *) atomic->lck); #endif } diff --git a/src/fccache.c b/src/fccache.c index 81985df..0a0bc27 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -131,7 +131,7 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) cache_hashed = FcStrPlus (cache_dir, cache_base); if (!cache_hashed) break; - (void) unlink ((char *) cache_hashed); + (void) FcUnlink ((char *) cache_hashed); FcStrFree (cache_hashed); } FcStrListDone (list); @@ -150,7 +150,7 @@ FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat) if (FcStat (cache_file, file_stat) < 0) return -1; #endif - fd = open((char *) cache_file, O_RDONLY | O_BINARY); + fd = FcOpen((char *) cache_file, O_RDONLY | O_BINARY); if (fd < 0) return fd; #ifndef _WIN32 @@ -802,10 +802,6 @@ bail1: } -#ifdef _WIN32 -#define mkdir(path,mode) _mkdir(path) -#endif - static FcBool FcMakeDirectory (const FcChar8 *dir) { @@ -818,10 +814,10 @@ FcMakeDirectory (const FcChar8 *dir) parent = FcStrDirname (dir); if (!parent) return FcFalse; - if (access ((char *) parent, F_OK) == 0) - ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; - else if (access ((char *) parent, F_OK) == -1) - ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; + if (FcAccess ((char *) parent, F_OK) == 0) + ret = FcMkdir ((char *) dir, 0755) == 0 && FcChmod ((char *) dir, 0755) == 0; + else if (FcAccess ((char *) parent, F_OK) == -1) + ret = FcMakeDirectory (parent) && (FcMkdir ((char *) dir, 0755) == 0) && FcChmod ((char *) dir, 0755) == 0; else ret = FcFalse; FcStrFree (parent); @@ -853,7 +849,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) if (!list) return FcFalse; while ((test_dir = FcStrListNext (list))) { - if (access ((char *) test_dir, W_OK) == 0) + if (FcAccess ((char *) test_dir, W_OK) == 0) { cache_dir = test_dir; break; @@ -863,7 +859,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) /* * If the directory doesn't exist, try to create it */ - if (access ((char *) test_dir, F_OK) == -1) { + if (FcAccess ((char *) test_dir, F_OK) == -1) { if (FcMakeDirectory (test_dir)) { cache_dir = test_dir; @@ -875,7 +871,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) /* * Otherwise, try making it writable */ - else if (chmod ((char *) test_dir, 0755) == 0) + else if (FcChmod ((char *) test_dir, 0755) == 0) { cache_dir = test_dir; /* Try to create CACHEDIR.TAG too */ @@ -904,7 +900,7 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) if (!FcAtomicLock (atomic)) goto bail3; - fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); + fd = FcOpen((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); if (fd == -1) goto bail4; @@ -978,23 +974,23 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); return FcFalse; } - if (access ((char *) cache_dir, W_OK) != 0) + if (FcAccess ((char *) cache_dir, W_OK) != 0) { if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: not cleaning %s cache directory\n", cache_dir, - access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); + FcAccess ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); goto bail0; } if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: cleaning cache directory\n", cache_dir); - d = opendir ((char *) cache_dir); + d = FcOpendir ((char *) cache_dir); if (!d) { perror ((char *) cache_dir); ret = FcFalse; goto bail0; } - while ((ent = readdir (d))) + while ((ent = FcReaddir (d))) { FcChar8 *file_name; const FcChar8 *target_dir; @@ -1025,7 +1021,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) else { target_dir = FcCacheDir (cache); - if (stat ((char *) target_dir, &target_stat) < 0) + if (FcStat ((char *) target_dir, &target_stat) < 0) { if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: %s: missing directory: %s \n", @@ -1035,7 +1031,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) } if (remove) { - if (unlink ((char *) file_name) < 0) + if (FcUnlink ((char *) file_name) < 0) { perror ((char *) file_name); ret = FcFalse; @@ -1045,7 +1041,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) FcStrFree (file_name); } - closedir (d); + FcClosedir (d); bail0: FcStrFree (dir_base); @@ -1368,7 +1364,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) if (!cache_dir) return FcFalse; - if (access ((char *) cache_dir, W_OK) == 0) + if (FcAccess ((char *) cache_dir, W_OK) == 0) { /* Create CACHEDIR.TAG */ cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG"); @@ -1379,7 +1375,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) goto bail1; if (!FcAtomicLock (atomic)) goto bail2; - fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644); + fd = FcOpen((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644); if (fd == -1) goto bail3; fp = fdopen(fd, "wb"); diff --git a/src/fccfg.c b/src/fccfg.c index d3752e5..bc40f2c 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -1747,7 +1747,7 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file) strcat ((char *) path, (char *) file); FcMemAlloc (FC_MEM_STRING, osize); - if (access ((char *) path, R_OK) == 0) + if (FcAccess ((char *) path, R_OK) == 0) return path; FcStrFree (path); diff --git a/src/fcdir.c b/src/fcdir.c index 2b476e8..a030db4 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -168,7 +168,7 @@ FcDirScanConfig (FcFontSet *set, if (FcDebug () & FC_DBG_SCAN) printf ("\tScanning dir %s\n", dir); - d = opendir ((char *) dir); + d = FcOpendir ((char *) dir); if (!d) { /* Don't complain about missing directories */ @@ -183,7 +183,7 @@ FcDirScanConfig (FcFontSet *set, ret = FcFalse; goto bail1; } - while ((e = readdir (d))) + while ((e = FcReaddir (d))) { if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN) { @@ -209,7 +209,7 @@ FcDirScanConfig (FcFontSet *set, bail2: FcStrSetDestroy (files); bail1: - closedir (d); + FcClosedir (d); bail: if (file) free (file); diff --git a/src/fcformat.c b/src/fcformat.c index 8eef7bb..d4287db 100644 --- a/src/fcformat.c +++ b/src/fcformat.c @@ -566,7 +566,11 @@ interpret_count (FcFormatContext *c, count++; } +#ifdef _WIN32 + _snprintf_s ((char *) buf_static, sizeof (buf_static), sizeof (buf_static), "%d", count); +#else snprintf ((char *) buf_static, sizeof (buf_static), "%d", count); +#endif FcStrBufString (buf, buf_static); return FcTrue; diff --git a/src/fcint.h b/src/fcint.h index c078575..de72cb9 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -41,7 +41,9 @@ #include <string.h> #include <ctype.h> #include <errno.h> +#ifdef HAVE_UNISTD_H #include <unistd.h> +#endif #include <stddef.h> #include <sys/types.h> #include <sys/stat.h> diff --git a/src/fcstat.c b/src/fcstat.c index d8663d0..d441b12 100644 --- a/src/fcstat.c +++ b/src/fcstat.c @@ -1,3 +1,4 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t -*- */ /* * Copyright © 2000 Keith Packard * Copyright © 2005 Patrick Lam @@ -55,6 +56,15 @@ typedef long long INT64; typedef __int64 INT64; #endif +static FcChar32 +FcStringHashW (const wchar_t * wstr) +{ + char * str = fc_utf16_to_utf8(wstr); + FcChar32 ret = FcStringHash(str); + free(str); + return ret; +} + /* Workaround for problems in the stat() in the Microsoft C library: * * 1) stat() uses FindFirstFile() to get the file @@ -75,14 +85,14 @@ typedef __int64 INT64; */ int -FcStat (const FcChar8 *file, struct stat *statb) +FcStatW (const wchar_t *wfile, struct stat *statb) { WIN32_FILE_ATTRIBUTE_DATA wfad; - char full_path_name[MAX_PATH]; - char *basename; + wchar_t wfull_path_name[MAX_PATH]; + wchar_t *wbasename; DWORD rc; - if (!GetFileAttributesEx ((LPCSTR) file, GetFileExInfoStandard, &wfad)) + if (!GetFileAttributesExW (wfile, GetFileExInfoStandard, &wfad)) return -1; statb->st_dev = 0; @@ -91,12 +101,12 @@ FcStat (const FcChar8 *file, struct stat *statb) * Call GetLongPathName() to get the spelling of the path name as it * is on disk. */ - rc = GetFullPathName ((LPCSTR) file, sizeof (full_path_name), full_path_name, &basename); - if (rc == 0 || rc > sizeof (full_path_name)) + rc = GetFullPathNameW (wfile, MAX_PATH, wfull_path_name, &wbasename); + if (rc == 0 || rc > MAX_PATH) return -1; - rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name)); - statb->st_ino = FcStringHash ((const FcChar8 *) full_path_name); + rc = GetLongPathNameW (wfull_path_name, wfull_path_name, MAX_PATH); + statb->st_ino = FcStringHashW (wfull_path_name); statb->st_mode = _S_IREAD | _S_IWRITE; statb->st_mode |= (statb->st_mode >> 3) | (statb->st_mode >> 6); @@ -121,6 +131,21 @@ FcStat (const FcChar8 *file, struct stat *statb) return 0; } +int +FcStat (const FcChar8 *file_utf8, struct stat *statb) +{ + wchar_t * wfile = fc_utf8_to_utf16(file_utf8); + int ret = FcStatW(wfile, statb); + free(wfile); + return ret; +} + +#if !defined(__MINGW32__) +int S_ISDIR(int statb_st_mode) +{ + return statb_st_mode & _S_IFDIR; +} +#endif #else int @@ -334,7 +359,7 @@ FcIsFsMmapSafe (int fd) FcBool FcIsFsMtimeBroken (const FcChar8 *dir) { - int fd = open ((const char *) dir, O_RDONLY); + int fd = FcOpen ((const char *) dir, O_RDONLY); if (fd != -1) { diff --git a/src/fcxml.c b/src/fcxml.c index 5edc867..13f0c41 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -25,8 +25,9 @@ #include "fcint.h" #include <fcntl.h> #include <stdarg.h> +#ifdef HAVE_DIRENT_H #include <dirent.h> - +#endif #ifdef ENABLE_LIBXML2 #include <libxml/parser.h> @@ -2764,6 +2765,7 @@ FcConfigParseAndLoadDir (FcConfig *config, const FcChar8 *dir, FcBool complain) { +#ifdef HAVE_DIRENT_H DIR *d; struct dirent *e; FcBool ret = FcTrue; @@ -2771,7 +2773,7 @@ FcConfigParseAndLoadDir (FcConfig *config, FcChar8 *base; FcStrSet *files; - d = opendir ((char *) dir); + d = FcOpendir ((char *) dir); if (!d) { if (complain) @@ -2801,8 +2803,8 @@ FcConfigParseAndLoadDir (FcConfig *config, if (FcDebug () & FC_DBG_CONFIG) printf ("\tScanning config dir %s\n", dir); - - while (ret && (e = readdir (d))) + + while (ret && (e = FcReaddir (d))) { int d_len; #define TAIL ".conf" @@ -2836,9 +2838,12 @@ bail3: bail2: free (file); bail1: - closedir (d); + FcClosedir (d); bail0: return ret || !complain; +#else +#error missing dirent.h +#endif } #ifdef _WIN32 @@ -2908,7 +2913,7 @@ FcConfigParseAndLoad (FcConfig *config, if (FcDebug () & FC_DBG_CONFIG) printf ("\tLoading config file %s\n", filename); - fd = open ((char *) filename, O_RDONLY); + fd = FcOpen ((char *) filename, O_RDONLY); if (fd == -1) { FcStrFree (filename); goto bail0; -- 1.7.9
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig