vbox的更動 56308 路徑 trunk/src/bldprogs
- 時間撮記:
- 2015-6-9 下午10:30:42 (9 年 以前)
- 位置:
- trunk/src/bldprogs
- 檔案:
-
- 修改 2 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/bldprogs/Makefile.kmk
r56301 r56308 42 42 scmstream.cpp \ 43 43 scmsubversion.cpp 44 ifdef VBOX_PATH_SUBVERSION_INCS 45 scm_INCS += $(VBOX_PATH_SUBVERSION_INCS) $(VBOX_PATH_APACHE_RUNTIME_INCS) 46 scm_DEFS += SCM_WITH_SVN_HEADERS 47 endif 44 48 45 49 BLDPROGS += VBoxCPP -
trunk/src/bldprogs/scmsubversion.cpp
r48959 r56308 5 5 6 6 /* 7 * Copyright (C) 2010-201 2Oracle Corporation7 * Copyright (C) 2010-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #define SCM_WITH OUT_LIBSVN18 #define SCM_WITH_DYNAMIC_LIB_SVN 19 19 20 20 /******************************************************************************* … … 25 25 #include <iprt/dir.h> 26 26 #include <iprt/env.h> 27 #include <iprt/err.h> 27 28 #include <iprt/file.h> 28 #include <iprt/err.h>29 29 #include <iprt/getopt.h> 30 #include <iprt/handle.h> 30 31 #include <iprt/initterm.h> 32 #include <iprt/ldr.h> 31 33 #include <iprt/mem.h> 32 34 #include <iprt/message.h> 33 35 #include <iprt/param.h> 34 36 #include <iprt/path.h> 37 #include <iprt/pipe.h> 38 #include <iprt/poll.h> 35 39 #include <iprt/process.h> 36 40 #include <iprt/stream.h> … … 38 42 39 43 #include "scm.h" 44 45 #if defined(SCM_WITH_DYNAMIC_LIB_SVN) && defined(SCM_WITH_SVN_HEADERS) 46 # include <svn_client.h> 47 #endif 48 49 50 /******************************************************************************* 51 * Defined Constants And Macros * 52 *******************************************************************************/ 53 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 54 # if defined(RT_OS_WINDOWS) && defined(RT_ARCH_X86) 55 # define APR_CALL __stdcall 56 # define SVN_CALL /* __stdcall ?? */ 57 # else 58 # define APR_CALL 59 # define SVN_CALL 60 # endif 61 #endif 62 #if defined(SCM_WITH_DYNAMIC_LIB_SVN) && !defined(SCM_WITH_SVN_HEADERS) 63 # define SVN_ERR_MISC_CATEGORY_START 200000 64 # define SVN_ERR_UNVERSIONED_RESOURCE (SVN_ERR_MISC_CATEGORY_START + 5) 65 #endif 66 67 68 /******************************************************************************* 69 * Structures and Typedefs * 70 *******************************************************************************/ 71 #if defined(SCM_WITH_DYNAMIC_LIB_SVN) && !defined(SCM_WITH_SVN_HEADERS) 72 typedef int apr_status_t; 73 typedef int64_t apr_time_t; 74 typedef struct apr_pool_t apr_pool_t; 75 typedef struct apr_hash_t apr_hash_t; 76 typedef struct apr_hash_index_t apr_hash_index_t; 77 typedef struct apr_array_header_t apr_array_header_t; 78 79 80 typedef struct svn_error_t 81 { 82 apr_status_t apr_err; 83 const char *_dbgr_message; 84 struct svn_error_t *_dbgr_child; 85 apr_pool_t *_dbgr_pool; 86 const char *_dbgr_file; 87 long _dbgr_line; 88 } svn_error_t; 89 typedef int svn_boolean_t; 90 typedef long int svn_revnum_t; 91 typedef struct svn_client_ctx_t svn_client_ctx_t; 92 typedef enum svn_opt_revision_kind 93 { 94 svn_opt_revision_unspecified = 0, 95 svn_opt_revision_number, 96 svn_opt_revision_date, 97 svn_opt_revision_committed, 98 svn_opt_revision_previous, 99 svn_opt_revision_base, 100 svn_opt_revision_working, 101 svn_opt_revision_head 102 } svn_opt_revision_kind; 103 typedef union svn_opt_revision_value_t 104 { 105 svn_revnum_t number; 106 apr_time_t date; 107 } svn_opt_revision_value_t; 108 typedef struct svn_opt_revision_t 109 { 110 svn_opt_revision_kind kind; 111 svn_opt_revision_value_t value; 112 } svn_opt_revision_t; 113 typedef enum svn_depth_t 114 { 115 svn_depth_unknown = -2, 116 svn_depth_exclude, 117 svn_depth_empty, 118 svn_depth_files, 119 svn_depth_immediates, 120 svn_depth_infinity 121 } svn_depth_t; 122 123 #endif /* SCM_WITH_DYNAMIC_LIB_SVN && !SCM_WITH_SVN_HEADERS */ 40 124 41 125 … … 49 133 kScmSvnVersion_1_6, 50 134 kScmSvnVersion_1_7, 135 kScmSvnVersion_1_8, 51 136 kScmSvnVersion_End 52 137 } g_enmSvnVersion = kScmSvnVersion_Ancient; 53 138 54 139 55 #ifdef SCM_WITHOUT_LIBSVN 140 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 141 /** Set if all the function pointers are valid. */ 142 static bool g_fSvnFunctionPointersValid; 143 /** @name SVN and APR imports. 144 * @{ */ 145 static apr_status_t (APR_CALL *g_pfnAprInitialize)(void); 146 static apr_hash_index_t * (APR_CALL *g_pfnAprHashFirst)(apr_pool_t *pPool, apr_hash_t *pHashTab); 147 static apr_hash_index_t * (APR_CALL *g_pfnAprHashNext)(apr_hash_index_t *pCurIdx); 148 static void * (APR_CALL *g_pfnAprHashThisVal)(apr_hash_index_t *pHashIdx); 149 static apr_pool_t * (SVN_CALL *g_pfnSvnPoolCreateEx)(apr_pool_t *pParent, void *pvAllocator); 150 static void (APR_CALL *g_pfnAprPoolClear)(apr_pool_t *pPool); 151 static void (APR_CALL *g_pfnAprPoolDestroy)(apr_pool_t *pPool); 152 153 static svn_error_t * (SVN_CALL *g_pfnSvnClientCreateContext)(svn_client_ctx_t **ppCtx, apr_pool_t *pPool); 154 static svn_error_t * (SVN_CALL *g_pfnSvnClientPropGet4)(apr_hash_t **ppHashProps, const char *pszPropName, 155 const char *pszTarget, const svn_opt_revision_t *pPeggedRev, 156 const svn_opt_revision_t *pRevision, svn_revnum_t *pActualRev, 157 svn_depth_t enmDepth, const apr_array_header_t *pChangeList, 158 svn_client_ctx_t *pCtx, apr_pool_t *pResultPool, 159 apr_pool_t *pScratchPool); 160 /**@} */ 161 #endif 162 163 56 164 57 165 /** … … 78 186 } 79 187 80 #include <iprt/handle.h>81 #include <iprt/pipe.h>82 #include <iprt/poll.h>83 188 84 189 /** … … 548 653 549 654 655 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 656 /** 657 * Attempts to resolve the necessary subversion and apache portable runtime APIs 658 * we require dynamically. 659 * 660 * Will set all global function pointers and g_fSvnFunctionPointersValid to true 661 * on success. 662 */ 663 static void scmSvnTryResolveFunctions(void) 664 { 665 char szPath[RTPATH_MAX]; 666 int rc = RTStrCopy(szPath, sizeof(szPath), g_szSvnPath); 667 if (RT_SUCCESS(rc)) 668 { 669 RTPathStripFilename(szPath); 670 char *pszEndPath = strchr(szPath, '\0'); 671 # ifdef RT_OS_WINDOWS 672 RTPathChangeToDosSlashes(szPath, false); 673 # endif 674 675 /* 676 * Try various prefixes/suffxies/locations. 677 */ 678 static struct 679 { 680 const char *pszPrefix; 681 const char *pszSuffix; 682 } const s_aVariations[] = 683 { 684 # ifdef RT_OS_WINDOWS 685 { "SlikSvn-lib", "-1.dll" }, /* SlikSVN */ 686 { "lib", "-1.dll" }, /* Win32Svn,CollabNet,++ */ 687 # elif defined(RT_OS_DARWIN) 688 { "../lib/lib", "-1.dylib" }, 689 # else 690 { "../lib/lib", ".so" }, 691 { "../lib/lib", "-1.so" }, 692 # endif 693 }; 694 for (unsigned iVar = 0; RT_ELEMENTS(s_aVariations); iVar++) 695 { 696 /* 697 * Try load the svn_client library ... 698 */ 699 struct 700 { 701 const char *pszBaseName; 702 RTLDRMOD hMod; 703 } aLibraries[] = 704 { 705 { "svn_client", NIL_RTLDRMOD }, 706 { "svn_subr", NIL_RTLDRMOD }, 707 { "apr", NIL_RTLDRMOD }, 708 }; 709 rc = VINF_SUCCESS; 710 unsigned iLib; 711 for (iLib = 0; iLib < RT_ELEMENTS(aLibraries) && RT_SUCCESS(rc); iLib++) 712 { 713 *pszEndPath = '\0'; 714 rc = RTPathAppend(szPath, sizeof(szPath), s_aVariations[iVar].pszPrefix); 715 if (RT_SUCCESS(rc)) 716 rc = RTStrCat(szPath, sizeof(szPath), aLibraries[iLib].pszBaseName); 717 if (RT_SUCCESS(rc)) 718 rc = RTStrCat(szPath, sizeof(szPath), s_aVariations[iVar].pszSuffix); 719 if (RT_SUCCESS(rc)) 720 { 721 # ifdef RT_OS_WINDOWS 722 RTPathChangeToDosSlashes(pszEndPath, false); 723 # endif 724 rc = RTLdrLoadEx(szPath, &aLibraries[iLib].hMod, RTLDRLOAD_FLAGS_NT_SEARCH_DLL_LOAD_DIR , NULL); 725 } 726 } 727 if (iLib == RT_ELEMENTS(aLibraries) && RT_SUCCESS(rc)) 728 { 729 static const struct 730 { 731 unsigned iLib; 732 const char *pszSymbol; 733 PFNRT *ppfn; 734 } s_aSymbols[] = 735 { 736 { 2, "apr_initialize", (PFNRT *)&g_pfnAprInitialize }, 737 { 2, "apr_hash_first", (PFNRT *)&g_pfnAprHashFirst }, 738 { 2, "apr_hash_next", (PFNRT *)&g_pfnAprHashNext }, 739 { 2, "apr_hash_this_val", (PFNRT *)&g_pfnAprHashThisVal }, 740 { 1, "svn_pool_create_ex", (PFNRT *)&g_pfnSvnPoolCreateEx }, 741 { 2, "apr_pool_clear", (PFNRT *)&g_pfnAprPoolClear }, 742 { 2, "apr_pool_destroy", (PFNRT *)&g_pfnAprPoolDestroy }, 743 { 0, "svn_client_create_context", (PFNRT *)&g_pfnSvnClientCreateContext }, 744 { 0, "svn_client_propget4", (PFNRT *)&g_pfnSvnClientPropGet4 }, 745 }; 746 for (unsigned i = 0; i < RT_ELEMENTS(s_aSymbols); i++) 747 { 748 rc = RTLdrGetSymbol(aLibraries[s_aSymbols[i].iLib].hMod, s_aSymbols[i].pszSymbol, 749 (void **)(uintptr_t)s_aSymbols[i].ppfn); 750 if (RT_FAILURE(rc)) 751 { 752 ScmVerbose(NULL, 0, "Failed to resolve '%s' in '%s'", 753 s_aSymbols[i].pszSymbol, aLibraries[s_aSymbols[i].iLib].pszBaseName); 754 break; 755 } 756 } 757 if (RT_SUCCESS(rc)) 758 { 759 apr_status_t rc = g_pfnAprInitialize(); 760 if (rc == 0) 761 { 762 ScmVerbose(NULL, 1, "Found subversion APIs.\n"); 763 g_fSvnFunctionPointersValid = true; 764 } 765 else 766 { 767 ScmVerbose(NULL, 0, "apr_initialize failed: %#x (%d)\n", rc, rc); 768 AssertMsgFailed(("%#x (%d)\n", rc, rc)); 769 } 770 return; 771 } 772 } 773 774 while (iLib-- > 0) 775 RTLdrClose(aLibraries[iLib].hMod); 776 } 777 } 778 } 779 #endif /* SCM_WITH_DYNAMIC_LIB_SVN */ 780 781 550 782 /** 551 783 * Finds the svn binary, updating g_szSvnPath and g_enmSvnVersion. … … 588 820 { 589 821 char *pszStripped = RTStrStrip(pszVersion); 590 if (RTStrVersionCompare(pszVersion, "1.7") >= 0) 822 if (RTStrVersionCompare(pszVersion, "1.8") >= 0) 823 g_enmSvnVersion = kScmSvnVersion_1_8; 824 else if (RTStrVersionCompare(pszVersion, "1.7") >= 0) 591 825 g_enmSvnVersion = kScmSvnVersion_1_7; 592 826 else if (RTStrVersionCompare(pszVersion, "1.6") >= 0) … … 598 832 else 599 833 g_enmSvnVersion = kScmSvnVersion_Ancient; 834 835 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 836 /* 837 * If we got version 1.8 or later, try see if we can locate a few of the 838 * simpler SVN APIs. 839 */ 840 g_fSvnFunctionPointersValid = false; 841 if (g_enmSvnVersion >= kScmSvnVersion_1_8) 842 scmSvnTryResolveFunctions(); 843 #endif 600 844 } 601 845 … … 658 902 } 659 903 660 #endif /* SCM_WITHOUT_LIBSVN */ 904 905 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 906 907 /** 908 * Wrapper around RTPathAbs. 909 * @returns Same as RTPathAbs. 910 * @param pszPath The relative path. 911 * @param pszAbsPath Where to return the absolute path. 912 * @param cbAbsPath Size of the @a pszAbsPath buffer. 913 */ 914 static int scmSvnAbsPath(const char *pszPath, char *pszAbsPath, size_t cbAbsPath) 915 { 916 int rc = RTPathAbs(pszPath, pszAbsPath, cbAbsPath); 917 # if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 918 if (RT_SUCCESS(rc)) 919 RTPathChangeToUnixSlashes(pszAbsPath, true /*fForce*/); 920 # endif 921 return rc; 922 } 923 924 925 /** 926 * Checks if @a pszPath exists in the current WC. 927 * 928 * @returns true, false or -1. In the latter case, please use the fallback. 929 * @param pszPath Path to the object that should be investigated. 930 */ 931 static int scmSvnIsObjectInWorkingCopy(const char *pszPath) 932 { 933 int rc = -1; 934 935 /* svn_client_propget4 and later requires absolute target path. */ 936 char szAbsPath[RTPATH_MAX]; 937 int rc2 = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath)); 938 if (RT_SUCCESS(rc2)) 939 { 940 /* Create calling context. */ 941 apr_pool_t *pPool = g_pfnSvnPoolCreateEx(NULL, NULL); 942 if (pPool) 943 { 944 svn_client_ctx_t *pCtx = NULL; 945 svn_error_t *pErr = g_pfnSvnClientCreateContext(&pCtx, pPool); 946 if (!pErr) 947 { 948 /* Make the call. */ 949 apr_hash_t *pHash = NULL; 950 svn_opt_revision_t Rev; 951 RT_ZERO(Rev); 952 Rev.kind = svn_opt_revision_base; 953 Rev.value.number = -1L; 954 pErr = g_pfnSvnClientPropGet4(&pHash, "svn:no-such-property", szAbsPath, &Rev, &Rev, 955 NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/, pCtx, pPool, pPool); 956 if (!pErr) 957 rc = true; 958 else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) 959 rc = false; 960 } 961 g_pfnAprPoolDestroy(pPool); 962 } 963 } 964 return rc; 965 } 966 967 #endif /* SCM_WITH_DYNAMIC_LIB_SVN */ 968 661 969 662 970 /** … … 668 976 bool ScmSvnIsInWorkingCopy(PSCMRWSTATE pState) 669 977 { 670 #ifdef SCM_WITHOUT_LIBSVN671 978 scmSvnFindSvnBinary(pState); 979 980 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 981 if (g_fSvnFunctionPointersValid) 982 { 983 int rc = scmSvnIsObjectInWorkingCopy(pState->pszFilename); 984 if (rc == (int)true || rc == (int)false) 985 return rc == (int)true; 986 } 987 988 /* Fallback: */ 989 #endif 672 990 if (g_enmSvnVersion < kScmSvnVersion_1_7) 673 991 { … … 691 1009 } 692 1010 } 693 694 #else695 NOREF(pState);696 #endif697 1011 return false; 698 1012 } 1013 699 1014 700 1015 /** … … 706 1021 bool ScmSvnIsDirInWorkingCopy(const char *pszDir) 707 1022 { 708 #ifdef SCM_WITHOUT_LIBSVN709 1023 scmSvnFindSvnBinary(NULL); 1024 1025 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 1026 if (g_fSvnFunctionPointersValid) 1027 { 1028 int rc = scmSvnIsObjectInWorkingCopy(pszDir); 1029 if (rc == (int)true || rc == (int)false) 1030 return rc == (int)true; 1031 } 1032 1033 /* Fallback: */ 1034 #endif 710 1035 if (g_enmSvnVersion < kScmSvnVersion_1_7) 711 1036 { … … 729 1054 } 730 1055 } 731 732 #else733 NOREF(pState);734 #endif735 1056 return false; 736 1057 } 1058 1059 1060 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 1061 /** 1062 * Checks if @a pszPath exists in the current WC. 1063 * 1064 * @returns IPRT status code - VERR_NOT_SUPPORT if fallback should be attempted. 1065 * @param pszPath Path to the object that should be investigated. 1066 * @param pszProperty The property name. 1067 * @param ppszValue Where to return the property value. Optional. 1068 */ 1069 static int scmSvnQueryPropertyUsingApi(const char *pszPath, const char *pszProperty, char **ppszValue) 1070 { 1071 int rc = VERR_NOT_SUPPORTED; 1072 1073 /* svn_client_propget4 and later requires absolute target path. */ 1074 char szAbsPath[RTPATH_MAX]; 1075 int rc2 = scmSvnAbsPath(pszPath, szAbsPath, sizeof(szAbsPath)); 1076 if (RT_SUCCESS(rc2)) 1077 { 1078 /* Create calling context. */ 1079 apr_pool_t *pPool = g_pfnSvnPoolCreateEx(NULL, NULL); 1080 if (pPool) 1081 { 1082 svn_client_ctx_t *pCtx = NULL; 1083 svn_error_t *pErr = g_pfnSvnClientCreateContext(&pCtx, pPool); 1084 if (!pErr) 1085 { 1086 /* Make the call. */ 1087 apr_hash_t *pHash = NULL; 1088 svn_opt_revision_t Rev; 1089 RT_ZERO(Rev); 1090 Rev.kind = svn_opt_revision_base; 1091 Rev.value.number = -1L; 1092 pErr = g_pfnSvnClientPropGet4(&pHash, pszProperty, szAbsPath, &Rev, &Rev, 1093 NULL /*pActualRev*/, svn_depth_empty, NULL /*pChangeList*/, pCtx, pPool, pPool); 1094 if (!pErr) 1095 { 1096 /* Get the first value, if any. */ 1097 rc = VERR_NOT_FOUND; 1098 apr_hash_index_t *pHashIdx = g_pfnAprHashFirst(pPool, pHash); 1099 if (pHashIdx) 1100 { 1101 const char **ppszFirst = (const char **)g_pfnAprHashThisVal(pHashIdx); 1102 if (ppszFirst && *ppszFirst) 1103 rc = RTStrDupEx(ppszValue, *ppszFirst); 1104 } 1105 } 1106 else if (pErr->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) 1107 rc = VERR_INVALID_STATE; 1108 else 1109 rc = VERR_GENERAL_FAILURE; 1110 } 1111 g_pfnAprPoolDestroy(pPool); 1112 } 1113 } 1114 return rc; 1115 } 1116 #endif /* SCM_WITH_DYNAMIC_LIB_SVN */ 1117 737 1118 738 1119 /** … … 751 1132 int ScmSvnQueryProperty(PSCMRWSTATE pState, const char *pszName, char **ppszValue) 752 1133 { 1134 int rc; 1135 753 1136 /* 754 1137 * Look it up in the scheduled changes. … … 766 1149 } 767 1150 768 #ifdef SCM_WITHOUT_LIBSVN769 int rc;770 1151 scmSvnFindSvnBinary(pState); 1152 1153 #ifdef SCM_WITH_DYNAMIC_LIB_SVN 1154 if (g_fSvnFunctionPointersValid) 1155 { 1156 rc = scmSvnQueryPropertyUsingApi(pState->pszFilename, pszName, ppszValue); 1157 if (rc != VERR_NOT_SUPPORTED) 1158 return rc; 1159 /* Fallback: */ 1160 } 1161 #endif 1162 771 1163 if (g_enmSvnVersion < kScmSvnVersion_1_7) 772 1164 { … … 915 1307 } 916 1308 return rc; 917 918 #else919 NOREF(pState);920 #endif921 return VERR_NOT_FOUND;922 1309 } 923 1310 … … 1031 1418 int ScmSvnApplyChanges(PSCMRWSTATE pState) 1032 1419 { 1033 #ifdef SCM_WITHOUT_LIBSVN1034 1420 scmSvnFindSvnBinary(pState); 1421 1422 #ifdef SCM_WITH_LATER 1423 if (0) 1424 { 1425 return ...; 1426 } 1427 1428 /* Fallback: */ 1429 #endif 1035 1430 1036 1431 /* … … 1055 1450 1056 1451 return VINF_SUCCESS; 1057 #else 1058 return VERR_NOT_IMPLEMENTED; 1059 #endif 1060 } 1061 1452 } 1453
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器