2012-11-02 18:13 UTC+0100 Viktor Szakats (harbour syenar.net)

* utils/hbmk2/hbmk2.prg
    ! fixed to use proper harbour root for finding missing
      function
    ! fixed to find missing functions regardless of casing
    ! fixed recent bug in the value of {HB_ADDONS} macro on
      *nix systems in certain configurations
    * cleanups to prev commits
This commit is contained in:
Viktor Szakats
2012-11-02 17:15:29 +00:00
parent 7967592720
commit b1b458112e
2 changed files with 172 additions and 157 deletions

View File

@@ -16,6 +16,15 @@
The license applies to all entries newer than 2009-04-28.
*/
2012-11-02 18:13 UTC+0100 Viktor Szakats (harbour syenar.net)
* utils/hbmk2/hbmk2.prg
! fixed to use proper harbour root for finding missing
function
! fixed to find missing functions regardless of casing
! fixed recent bug in the value of {HB_ADDONS} macro on
*nix systems in certain configurations
* cleanups to prev commits
2012-11-02 16:18 UTC+0100 Viktor Szakats (harbour syenar.net)
* utils/hbmk2/hbmk2.prg
! minor follow up, fixing to hint function names starting

View File

@@ -332,159 +332,160 @@ EXTERNAL hbmk_KEYW
#define _HBMK_cHB_INSTALL_DYN 15
#define _HBMK_cHB_INSTALL_INC 16
#define _HBMK_cHB_INSTALL_ADD 17
#define _HBMK_cHB_INSTALL_CON 18
#define _HBMK_lGUI 18
#define _HBMK_lMT 19
#define _HBMK_lPIC 20
#define _HBMK_lDEBUG 21
#define _HBMK_nHEAD 22
#define _HBMK_aINCPATH 23
#define _HBMK_lREBUILD 24
#define _HBMK_lCLEAN 25
#define _HBMK_lTRACE 26
#define _HBMK_lDONTEXEC 27
#define _HBMK_nHBMODE 28
#define _HBMK_cUILNG 29
#define _HBMK_aLIBUSER 30
#define _HBMK_aLIBUSERFWK 31
#define _HBMK_aLIBUSERGT 32
#define _HBMK_aLIBUSERSYS 33
#define _HBMK_aLIBUSERSYSPRE 34
#define _HBMK_aLIBFILTEROUT 35
#define _HBMK_aLIBPATH 36
#define _HBMK_aINSTPATH 37
#define _HBMK_aOPTC 38
#define _HBMK_aOPTCUSER 39
#define _HBMK_aOPTCX 40
#define _HBMK_aOPTCPPX 41
#define _HBMK_aOPTPRG 42
#define _HBMK_aOPTRES 43
#define _HBMK_aOPTL 44
#define _HBMK_aOPTLPOST 45
#define _HBMK_aOPTA 46
#define _HBMK_aOPTD 47
#define _HBMK_aOPTDPOST 48
#define _HBMK_aOPTI 49
#define _HBMK_lCPP 50
#define _HBMK_lSHARED 51
#define _HBMK_lSTATICFULL 52
#define _HBMK_lSHAREDDIST 53
#define _HBMK_lNULRDD 54
#define _HBMK_lMAP 55
#define _HBMK_lBEEP 56
#define _HBMK_lSTRIP 57
#define _HBMK_lOPTIM 58
#define _HBMK_nCOMPR 59
#define _HBMK_nWARN 60
#define _HBMK_lRUN 61
#define _HBMK_lINC 62
#define _HBMK_lREBUILDPO 63
#define _HBMK_lMINIPO 64
#define _HBMK_lWINUNI 65
#define _HBMK_nCONF 66
#define _HBMK_lIGNOREERROR 67
#define _HBMK_lIMPLIB 68
#define _HBMK_lHBCPPMM 69
#define _HBMK_hDEP 70
#define _HBMK_lGUI 19
#define _HBMK_lMT 20
#define _HBMK_lPIC 21
#define _HBMK_lDEBUG 22
#define _HBMK_nHEAD 23
#define _HBMK_aINCPATH 24
#define _HBMK_lREBUILD 25
#define _HBMK_lCLEAN 26
#define _HBMK_lTRACE 27
#define _HBMK_lDONTEXEC 28
#define _HBMK_nHBMODE 29
#define _HBMK_cUILNG 30
#define _HBMK_aLIBUSER 31
#define _HBMK_aLIBUSERFWK 32
#define _HBMK_aLIBUSERGT 33
#define _HBMK_aLIBUSERSYS 34
#define _HBMK_aLIBUSERSYSPRE 35
#define _HBMK_aLIBFILTEROUT 36
#define _HBMK_aLIBPATH 37
#define _HBMK_aINSTPATH 38
#define _HBMK_aOPTC 39
#define _HBMK_aOPTCUSER 40
#define _HBMK_aOPTCX 41
#define _HBMK_aOPTCPPX 42
#define _HBMK_aOPTPRG 43
#define _HBMK_aOPTRES 44
#define _HBMK_aOPTL 45
#define _HBMK_aOPTLPOST 46
#define _HBMK_aOPTA 47
#define _HBMK_aOPTD 48
#define _HBMK_aOPTDPOST 49
#define _HBMK_aOPTI 50
#define _HBMK_lCPP 51
#define _HBMK_lSHARED 52
#define _HBMK_lSTATICFULL 53
#define _HBMK_lSHAREDDIST 54
#define _HBMK_lNULRDD 55
#define _HBMK_lMAP 56
#define _HBMK_lBEEP 57
#define _HBMK_lSTRIP 58
#define _HBMK_lOPTIM 59
#define _HBMK_nCOMPR 60
#define _HBMK_nWARN 61
#define _HBMK_lRUN 62
#define _HBMK_lINC 63
#define _HBMK_lREBUILDPO 64
#define _HBMK_lMINIPO 65
#define _HBMK_lWINUNI 66
#define _HBMK_nCONF 67
#define _HBMK_lIGNOREERROR 68
#define _HBMK_lIMPLIB 69
#define _HBMK_lHBCPPMM 70
#define _HBMK_hDEP 71
#define _HBMK_lCreateLib 71
#define _HBMK_lCreateDyn 72
#define _HBMK_lCreateImpLib 73
#define _HBMK_lCreatePPO 74
#define _HBMK_lCreateHRB 75
#define _HBMK_lCreateLib 72
#define _HBMK_lCreateDyn 73
#define _HBMK_lCreateImpLib 74
#define _HBMK_lCreatePPO 75
#define _HBMK_lCreateHRB 76
#define _HBMK_lDynVM 76
#define _HBMK_lDynVM 77
#define _HBMK_lBLDFLGP 77
#define _HBMK_lBLDFLGC 78
#define _HBMK_lBLDFLGL 79
#define _HBMK_lBLDFLGP 78
#define _HBMK_lBLDFLGC 79
#define _HBMK_lBLDFLGL 80
#define _HBMK_cFIRST 80
#define _HBMK_aPRG 81
#define _HBMK_aC 82
#define _HBMK_aCPP 83
#define _HBMK_aRESSRC 84
#define _HBMK_aRESCMP 85
#define _HBMK_aOBJUSER 86
#define _HBMK_aICON 87
#define _HBMK_cMANIFEST 88
#define _HBMK_aIMPLIBSRC 89
#define _HBMK_aDEF 90
#define _HBMK_aINSTFILE 91
#define _HBMK_hDEPTS 92
#define _HBMK_aREQUEST 93
#define _HBMK_cFIRST 81
#define _HBMK_aPRG 82
#define _HBMK_aC 83
#define _HBMK_aCPP 84
#define _HBMK_aRESSRC 85
#define _HBMK_aRESCMP 86
#define _HBMK_aOBJUSER 87
#define _HBMK_aICON 88
#define _HBMK_cMANIFEST 89
#define _HBMK_aIMPLIBSRC 90
#define _HBMK_aDEF 91
#define _HBMK_aINSTFILE 92
#define _HBMK_hDEPTS 93
#define _HBMK_aREQUEST 94
#define _HBMK_aPO 94
#define _HBMK_cHBL 95
#define _HBMK_cHBLDir 96
#define _HBMK_aLNG 97
#define _HBMK_cPO 98
#define _HBMK_aPO 95
#define _HBMK_cHBL 96
#define _HBMK_cHBLDir 97
#define _HBMK_aLNG 98
#define _HBMK_cPO 99
#define _HBMK_hPLUGINHRB 99
#define _HBMK_hPLUGINVars 100
#define _HBMK_aPLUGINPars 101
#define _HBMK_hPLUGINExt 102
#define _HBMK_hPLUGINHRB 100
#define _HBMK_hPLUGINVars 101
#define _HBMK_aPLUGINPars 102
#define _HBMK_hPLUGINExt 103
#define _HBMK_lDEBUGTIME 103
#define _HBMK_lDEBUGINC 104
#define _HBMK_lDEBUGSTUB 105
#define _HBMK_lDEBUGI18N 106
#define _HBMK_lDEBUGDEPD 107
#define _HBMK_lDEBUGPARS 108
#define _HBMK_lDEBUGTIME 104
#define _HBMK_lDEBUGINC 105
#define _HBMK_lDEBUGSTUB 106
#define _HBMK_lDEBUGI18N 107
#define _HBMK_lDEBUGDEPD 108
#define _HBMK_lDEBUGPARS 109
#define _HBMK_cCCPATH 109
#define _HBMK_cCCPREFIX 110
#define _HBMK_cCCPOSTFIX 111
#define _HBMK_cCCEXT 112
#define _HBMK_cCCPATH 110
#define _HBMK_cCCPREFIX 111
#define _HBMK_cCCPOSTFIX 112
#define _HBMK_cCCEXT 113
#define _HBMK_cWorkDir 113
#define _HBMK_cWorkDirDynSub 114
#define _HBMK_nCmd_Esc 115
#define _HBMK_nScr_Esc 116
#define _HBMK_nCmd_FNF 117
#define _HBMK_nScr_FNF 118
#define _HBMK_nErrorLevel 119
#define _HBMK_cWorkDir 114
#define _HBMK_cWorkDirDynSub 115
#define _HBMK_nCmd_Esc 116
#define _HBMK_nScr_Esc 117
#define _HBMK_nCmd_FNF 118
#define _HBMK_nScr_FNF 119
#define _HBMK_nErrorLevel 120
#define _HBMK_cPROGDIR 120
#define _HBMK_cPROGNAME 121
#define _HBMK_cPROGDIR 121
#define _HBMK_cPROGNAME 122
#define _HBMK_hAUTOHBC 122 /* trigger header => .hbc associations */
#define _HBMK_hAUTOHBCFOUND 123 /* trigger headers found */
#define _HBMK_hAUTOHBC 123 /* trigger header => .hbc associations */
#define _HBMK_hAUTOHBCFOUND 124 /* trigger headers found */
#define _HBMK_aDEPTHBC 124 /* .hbc references found */
#define _HBMK_hDEPTSDIR 125 /* Header dirs found for dependencies */
#define _HBMK_aDEPTHBC 125 /* .hbc references found */
#define _HBMK_hDEPTSDIR 126 /* Header dirs found for dependencies */
#define _HBMK_lStopAfterInit 126
#define _HBMK_lStopAfterHarbour 127
#define _HBMK_lStopAfterInit 127
#define _HBMK_lStopAfterHarbour 128
#define _HBMK_nCOMPVer 128
#define _HBMK_lDEPIMPLIB 129 /* Generate import libs configured in dependecy specification */
#define _HBMK_lInstForce 130 /* Force to install target even if was up to date */
#define _HBMK_lAutoHBM 131 /* Toggles processing of hbmk.hbm file in current directory */
#define _HBMK_lContainer 132 /* Target type: container */
#define _HBMK_lShowLevel 133 /* Show project nesting level in all output lines */
#define _HBMK_hFiles 134 /* Cache for the header parser (common for C and Harbour) */
#define _HBMK_cDynLibPrefix 135 /* Dynamic lib filename prefix */
#define _HBMK_cDynLibExt 136 /* Dynamic lib filename extension */
#define _HBMK_aLINK 137 /* Links to be created and pointing to the target */
#define _HBMK_hDEPTMACRO 138 /* Links to be created and pointing to the target */
#define _HBMK_cC 139 /* C dialect */
#define _HBMK_cCPP 140 /* C++ dialect */
#define _HBMK_aLIB_BASE_WARN 141
#define _HBMK_nCOMPVer 129
#define _HBMK_lDEPIMPLIB 130 /* Generate import libs configured in dependecy specification */
#define _HBMK_lInstForce 131 /* Force to install target even if was up to date */
#define _HBMK_lAutoHBM 132 /* Toggles processing of hbmk.hbm file in current directory */
#define _HBMK_lContainer 133 /* Target type: container */
#define _HBMK_lShowLevel 134 /* Show project nesting level in all output lines */
#define _HBMK_hFiles 135 /* Cache for the header parser (common for C and Harbour) */
#define _HBMK_cDynLibPrefix 136 /* Dynamic lib filename prefix */
#define _HBMK_cDynLibExt 137 /* Dynamic lib filename extension */
#define _HBMK_aLINK 138 /* Links to be created and pointing to the target */
#define _HBMK_hDEPTMACRO 139 /* Links to be created and pointing to the target */
#define _HBMK_cC 140 /* C dialect */
#define _HBMK_cCPP 141 /* C++ dialect */
#define _HBMK_aLIB_BASE_WARN 142
#define _HBMK_aArgs 142
#define _HBMK_nArgTarget 143
#define _HBMK_lPause 144
#define _HBMK_nLevel 145
#define _HBMK_aArgs 143
#define _HBMK_nArgTarget 144
#define _HBMK_lPause 145
#define _HBMK_nLevel 146
#define _HBMK_cHBX 146
#define _HBMK_cHBX 147
#define _HBMK_aGT 147
#define _HBMK_cCPPRG 148
#define _HBMK_aGT 148
#define _HBMK_cCPPRG 149
#define _HBMK_lDumpInfo 149
#define _HBMK_lDumpInfo 150
#define _HBMK_MAX_ 149
#define _HBMK_MAX_ 150
#define _HBMK_DEP_CTRL_MARKER ".control." /* must be an invalid path */
@@ -1111,32 +1112,37 @@ STATIC PROCEDURE hbmk_harbour_dirlayout_init( hbmk, l_cHB_INSTALL_PREFIX )
AAdd( hbmk[ _HBMK_aLIBPATH ], hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_CONTRIB + hb_ps() + "%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_ADDONS + hb_ps() + "%{hb_name}" )
#if defined( __PLATFORM__UNIX )
IF hb_DirExists( "/opt/harbour" )
IF hb_DirExists( tmp := "/opt/harbour" )
IF Empty( hbmk[ _HBMK_cHB_INSTALL_ADD ] )
hbmk[ _HBMK_cHB_INSTALL_ADD ] := "/opt/harbour/" + _HBMK_SPECDIR_ADDONS
hbmk[ _HBMK_cHB_INSTALL_CON ] := tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB
hbmk[ _HBMK_cHB_INSTALL_ADD ] := tmp + hb_ps() + _HBMK_SPECDIR_ADDONS
ENDIF
AAdd( hbmk[ _HBMK_aLIBPATH ], "/opt/harbour/" + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], "/opt/harbour/" + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
ENDIF
IF hb_DirExists( "/usr/local/share/harbour" )
IF hb_DirExists( tmp := "/usr/local/share/harbour" )
IF Empty( hbmk[ _HBMK_cHB_INSTALL_ADD ] )
hbmk[ _HBMK_cHB_INSTALL_ADD ] := "/opt/harbour/" + _HBMK_SPECDIR_ADDONS
hbmk[ _HBMK_cHB_INSTALL_CON ] := tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB
hbmk[ _HBMK_cHB_INSTALL_ADD ] := tmp + hb_ps() + _HBMK_SPECDIR_ADDONS
ENDIF
AAdd( hbmk[ _HBMK_aLIBPATH ], "/usr/local/share/harbour/" + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], "/usr/local/share/harbour/" + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
ENDIF
IF hb_DirExists( "/usr/share/harbour" )
IF hb_DirExists( tmp := "/usr/share/harbour" )
IF Empty( hbmk[ _HBMK_cHB_INSTALL_ADD ] )
hbmk[ _HBMK_cHB_INSTALL_ADD ] := "/opt/harbour/" + _HBMK_SPECDIR_ADDONS
hbmk[ _HBMK_cHB_INSTALL_CON ] := tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB
hbmk[ _HBMK_cHB_INSTALL_ADD ] := tmp + hb_ps() + _HBMK_SPECDIR_ADDONS
ENDIF
AAdd( hbmk[ _HBMK_aLIBPATH ], "/usr/share/harbour/" + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], "/usr/share/harbour/" + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_CONTRIB + "/%{hb_name}" )
AAdd( hbmk[ _HBMK_aLIBPATH ], tmp + hb_ps() + _HBMK_SPECDIR_ADDONS + "/%{hb_name}" )
ENDIF
IF Empty( hbmk[ _HBMK_cHB_INSTALL_ADD ] )
hbmk[ _HBMK_cHB_INSTALL_CON ] := hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_CONTRIB
hbmk[ _HBMK_cHB_INSTALL_ADD ] := hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_ADDONS
ENDIF
#endif
IF Empty( hbmk[ _HBMK_cHB_INSTALL_ADD ] )
hbmk[ _HBMK_cHB_INSTALL_CON ] := hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_CONTRIB
hbmk[ _HBMK_cHB_INSTALL_ADD ] := hb_PathNormalize( hb_DirSepAdd( l_cHB_INSTALL_PREFIX ) ) + _HBMK_SPECDIR_ADDONS
ENDIF
@@ -12208,7 +12214,7 @@ STATIC FUNCTION MacOSXFiles( hbmk, nType, cPROGNAME )
STATIC PROCEDURE AdviseMissingLibs( hbmk, cOutput )
LOCAL hAll := GetListOfFunctionsKnown()
LOCAL hAll := GetListOfFunctionsKnown( hbmk )
LOCAL aFunction := ExtractHarbourSymbols( cOutput )
LOCAL cFunction
LOCAL aLib
@@ -12217,6 +12223,8 @@ STATIC PROCEDURE AdviseMissingLibs( hbmk, cOutput )
LOCAL hNeeded := { => }
hb_HCaseMatch( hAll, .F. )
FOR EACH cFunction IN aFunction DESCEND
IF cFunction $ hAll
FOR EACH cLib IN hb_ATokens( hAll[ cFunction ], "," )
@@ -12254,10 +12262,8 @@ STATIC FUNCTION LibReferenceToOption( cLib )
ELSE
lInstalled := hb_FileExists( cRoot + hb_ps() + hb_FNameExtSet( PathSepToSelf( cLib ), ".hbc" ) )
/* detect autofind libs */
IF ( Left( cLib, Len( "contrib" + "/" ) ) == "contrib" + "/" .AND. ;
"contrib" + "/" + hb_FNameName( cLib ) + "/" + hb_FNameName( cLib ) + ".hbx" == cLib ) .OR. ;
( Left( cLib, Len( "addons" + "/" ) ) == "addons" + "/" .AND. ;
"addons" + "/" + hb_FNameName( cLib ) + "/" + hb_FNameName( cLib ) + ".hbx" == cLib )
IF ( Left( cLib, Len( _HBMK_SPECDIR_CONTRIB + "/" ) ) == _HBMK_SPECDIR_CONTRIB + "/" .AND. _HBMK_SPECDIR_CONTRIB + "/" + hb_FNameName( cLib ) + "/" + hb_FNameName( cLib ) + ".hbx" == cLib ) .OR. ;
( Left( cLib, Len( _HBMK_SPECDIR_ADDONS + "/" ) ) == _HBMK_SPECDIR_ADDONS + "/" .AND. _HBMK_SPECDIR_ADDONS + "/" + hb_FNameName( cLib ) + "/" + hb_FNameName( cLib ) + ".hbx" == cLib )
cLib := hb_FNameName( cLib ) + ".hbc"
ELSE
cLib := hb_FNameExtSet( PathSepToSelf( cLib ), ".hbc" )
@@ -12286,9 +12292,9 @@ STATIC FUNCTION ExtractHarbourSymbols( cString )
RETURN aList
STATIC FUNCTION GetListOfFunctionsKnown()
LOCAL cRoot := hb_DirBase() + ".." + hb_ps()
LOCAL cFileName := hb_DirBase() + "hbmk2.hbr"
STATIC FUNCTION GetListOfFunctionsKnown( hbmk )
LOCAL cFileName := hb_DirBase() + _SELF_NAME_ + ".hbr" /* Experimental name. not final. */
LOCAL hAll := iif( hb_FileExists( cFileName ), hb_Deserialize( hb_ZUncompress( hb_MemoRead( cFileName ) ) ), { => } )
@@ -12300,8 +12306,8 @@ STATIC FUNCTION GetListOfFunctionsKnown()
hAll[ "HB_COMPILEBUF" ] := ;
hAll[ "HB_COMPILEFROMBUFF" ] := "(hbcplr)"
GetListOfFunctionsKnownWalkDir( cRoot + "contrib", cRoot, hAll )
GetListOfFunctionsKnownWalkDir( cRoot + "addons", cRoot, hAll )
GetListOfFunctionsKnownWalkDir( hbmk[ _HBMK_cHB_INSTALL_CON ], hb_FNameDir( hbmk[ _HBMK_cHB_INSTALL_CON ] ), hAll )
GetListOfFunctionsKnownWalkDir( hbmk[ _HBMK_cHB_INSTALL_ADD ], hb_FNameDir( hbmk[ _HBMK_cHB_INSTALL_ADD ] ), hAll )
RETURN hAll
@@ -12316,13 +12322,13 @@ STATIC PROCEDURE GetListOfFunctionsKnownWalkDir( cDir, cRoot, hAll )
ELSEIF "D" $ aFile[ F_ATTR ]
GetListOfFunctionsKnownWalkDir( cDir + aFile[ F_NAME ] + hb_ps(), cRoot, hAll )
ELSEIF hb_FNameExt( aFile[ F_NAME ] ) == ".hbx"
GetListOfFunctionsKnownProcessHBX( cDir + aFile[ F_NAME ], cRoot, hAll )
GetListOfFunctionsKnownLoadHBX( cDir + aFile[ F_NAME ], cRoot, hAll )
ENDIF
NEXT
RETURN
STATIC FUNCTION GetListOfFunctionsKnownProcessHBX( cFileName, cRoot, hAll )
STATIC FUNCTION GetListOfFunctionsKnownLoadHBX( cFileName, cRoot, hAll )
LOCAL cName := StrTran( SubStr( cFileName, Len( cRoot ) + 1 ), "\", "/" )