static int CALLBACK FontEnumCallBack( LOGFONT * lplf, TEXTMETRIC * lpntm, DWORD dwFontType, LPVOID pArray ) { PHB_ITEM pSubItems = hb_itemArrayNew( 4 ); HB_ARRAYSETSTR( pSubItems, 1, lplf->lfFaceName ); hb_arraySetL( pSubItems, 2, ( lplf->lfPitchAndFamily & FIXED_PITCH ) != 0 ); hb_arraySetL( pSubItems, 3, ( dwFontType & TRUETYPE_FONTTYPE ) != 0 ); hb_arraySetNL( pSubItems, 4, lpntm->tmCharSet ); hb_arrayAddForward( ( PHB_ITEM ) pArray, pSubItems ); hb_itemRelease( pSubItems ); return 1; }
PHB_ITEM hb_fsDirectory( const char * pszDirSpec, const char * pszAttributes, HB_BOOL fDateTime ) { PHB_ITEM pDir = hb_itemArrayNew( 0 ); char * pszFree = NULL; PHB_FFIND ffind; HB_FATTR ulMask; /* Get the passed attributes and convert them to Harbour Flags */ ulMask = HB_FA_ARCHIVE | HB_FA_READONLY; if( pszAttributes && *pszAttributes ) ulMask |= hb_fsAttrEncode( pszAttributes ); if( pszDirSpec && *pszDirSpec ) { if( ulMask != HB_FA_LABEL ) { /* CA-Cl*pper compatible behavior - add all file mask when * last character is directory or drive separator */ HB_SIZE nLen = strlen( pszDirSpec ) - 1; #ifdef HB_OS_HAS_DRIVE_LETTER if( pszDirSpec[ nLen ] == HB_OS_PATH_DELIM_CHR || pszDirSpec[ nLen ] == HB_OS_DRIVE_DELIM_CHR ) #else if( pszDirSpec[ nLen ] == HB_OS_PATH_DELIM_CHR ) #endif pszDirSpec = pszFree = hb_xstrcpy( NULL, pszDirSpec, HB_OS_ALLFILE_MASK, NULL ); } } else pszDirSpec = HB_OS_ALLFILE_MASK; /* Get the file list */ if( ( ffind = hb_fsFindFirst( pszDirSpec, ulMask ) ) != NULL ) { PHB_ITEM pSubarray = hb_itemNew( NULL ); do { char buffer[ 32 ]; hb_arrayNew ( pSubarray, F_LEN ); hb_arraySetC ( pSubarray, F_NAME, ffind->szName ); hb_arraySetNInt( pSubarray, F_SIZE, ffind->size ); hb_arraySetC ( pSubarray, F_TIME, ffind->szTime ); hb_arraySetC ( pSubarray, F_ATTR, hb_fsAttrDecode( ffind->attr, buffer ) ); if( fDateTime ) hb_arraySetTDT( pSubarray, F_DATE, ffind->lDate, ffind->lTime ); else hb_arraySetDL ( pSubarray, F_DATE, ffind->lDate ); /* Don't exit when array limit is reached */ hb_arrayAddForward( pDir, pSubarray ); } while( hb_fsFindNext( ffind ) ); hb_itemRelease( pSubarray ); hb_fsFindClose( ffind ); } if( pszFree ) hb_xfree( pszFree ); return pDir; }
static void hb_ParseLine( PHB_ITEM pReturn, const char * szText, int iDelimiter, int * iWord ) { if( szText ) { HB_ISIZ nLen = strlen( szText ); if( nLen > 0 ) { PHB_ITEM pTemp = hb_itemNew( NULL ); HB_ISIZ i = 0; int word_count = 0; /* booked enough memory */ char * szResult = ( char * ) hb_xgrab( nLen + 1 ); #if 0 while( nLen ) { if( szText[ nLen - 1 ] && ! HB_ISSPACE( szText[ nLen - 1 ] ) ) break; nLen--; } szText[ nLen ] = 0; nLen = strlen( szText ); #endif while( i < nLen ) { HB_ISIZ ui = 0; hb_xmemset( szResult, ' ', nLen + 1 ); /* an '"' found, loop until the next one is found */ if( szText[ i ] == '"' ) { /* an '"' after '"' ? */ if( szText[ i + 1 ] != '"' ) szResult[ ui ] = szText[ i + 1 ]; else szResult[ ui ] = '\0'; ++i; while( ++i < nLen ) { if( szText[ i - 1 ] == '"' ) { szResult[ ui + 1 ] = '\0'; break; } else { if( szText[ i ] == '"' ) szResult[ ui + 1 ] = '\0'; else szResult[ ++ui ] = szText[ i ]; } } word_count++; hb_arrayAddForward( pReturn, hb_itemPutC( pTemp, szResult ) ); } /* delimiter found */ else if( szText[ i ] == iDelimiter ) { /* first delimiter found but no word yet */ if( word_count == 0 ) { /* add an empty string */ szResult[ ui ] = '\0'; } else { /* we have already have the first word */ /* check next character */ if( szText[ i - 1 ] == iDelimiter ) { /* delimiter after delimiter */ /* just add an empty string */ szResult[ ui ] = '\0'; } else { /* ",,0" */ /* it is not a delimiter */ /* move to next character */ ++i; szResult[ ui ] = szText[ i ]; while( ++i < nLen ) { if( szText[ i ] == iDelimiter ) break; else szResult[ ++ui ] = szText[ i ]; } } } word_count++; szResult[ ui + 1 ] = '\0'; hb_arrayAddForward( pReturn, hb_itemPutC( pTemp, szResult ) ); } else { szResult[ ui ] = szText[ i ]; while( ++i < nLen ) { if( szText[ i ] == iDelimiter ) { szResult[ ui + 1 ] = '\0'; break; } else if( szText[ i ] == '"' ) { szResult[ ui ] = szText[ i + 1 ]; ++i; while( ++i < nLen ) { if( szText[ i - 1 ] == '"' ) { szResult[ ui + 1 ] = '\0'; break; } else { if( szText[ i ] == '"' ) { szResult[ ui + 1 ] = '\0'; break; } else szResult[ ++ui ] = szText[ i ]; } } } else szResult[ ++ui ] = szText[ i ]; } word_count++; szResult[ ui + 1 ] = '\0'; hb_arrayAddForward( pReturn, hb_itemPutC( pTemp, szResult ) ); } i++; } /* last character in passed string is a delimiter */ /* just add an empty string */ if( szText[ nLen - 1 ] == iDelimiter ) { word_count++; hb_arrayAddForward( pReturn, hb_itemPutC( pTemp, NULL ) ); } /* store number of words */ *iWord = word_count; /* clean up */ hb_xfree( szResult ); hb_itemRelease( pTemp ); } } }
static HB_BOOL hb_regex( int iRequest ) { HB_REGMATCH aMatches[ HB_REGMATCH_SIZE( REGEX_MAX_GROUPS ) ]; PHB_ITEM pRetArray, pMatch, pString; int i, iMatches, iMaxMatch; HB_BOOL fResult = HB_FALSE; PHB_REGEX pRegEx; const char * pszString; HB_SIZE nLen; pString = hb_param( 2, HB_IT_STRING ); if( ! pString ) { hb_errRT_BASE_SubstR( EG_ARG, 3014, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); return HB_FALSE; } pRegEx = hb_regexGet( hb_param( 1, HB_IT_ANY ), ( ! hb_parldef( 3, 1 ) ? HBREG_ICASE : 0 ) | ( hb_parl( 4 ) ? HBREG_NEWLINE : 0 ) ); if( ! pRegEx ) return HB_FALSE; pszString = hb_itemGetCPtr( pString ); nLen = hb_itemGetCLen( pString ); iMaxMatch = iRequest == 0 || iRequest == 4 || iRequest == 5 ? REGEX_MAX_GROUPS : 1; iMatches = hb_regexec( pRegEx, pszString, nLen, iMaxMatch, aMatches ); if( iMatches > 0 ) { switch( iRequest ) { case 0: pRetArray = hb_itemArrayNew( iMatches ); for( i = 0; i < iMatches; i++ ) { if( HB_REGMATCH_EO( aMatches, i ) > -1 ) hb_arraySetCL( pRetArray, i + 1, pszString + HB_REGMATCH_SO( aMatches, i ), HB_REGMATCH_EO( aMatches, i ) - HB_REGMATCH_SO( aMatches, i ) ); else hb_arraySetCL( pRetArray, i + 1, NULL, 0 ); } hb_itemReturnRelease( pRetArray ); fResult = HB_TRUE; break; case 1: /* LIKE */ fResult = HB_REGMATCH_SO( aMatches, 0 ) == 0 && ( HB_SIZE ) HB_REGMATCH_EO( aMatches, 0 ) == nLen; break; case 2: /* MATCH ( HAS ) */ fResult = HB_TRUE; break; case 3: /* SPLIT */ iMaxMatch = hb_parni( 5 ); pRetArray = hb_itemArrayNew( 0 ); pMatch = hb_itemNew( NULL ); iMatches = 0; do { hb_itemPutCL( pMatch, pszString, HB_REGMATCH_SO( aMatches, 0 ) ); hb_arrayAddForward( pRetArray, pMatch ); nLen -= HB_REGMATCH_EO( aMatches, 0 ); pszString += HB_REGMATCH_EO( aMatches, 0 ); iMatches++; } while( HB_REGMATCH_EO( aMatches, 0 ) > 0 && nLen && ( iMaxMatch == 0 || iMatches < iMaxMatch ) && hb_regexec( pRegEx, pszString, nLen, 1, aMatches ) > 0 ); /* last match must be done also in case that pszString is empty; this would mean an empty split field at the end of the string */ /* if( nLen ) */ { hb_itemPutCL( pMatch, pszString, nLen ); hb_arrayAddForward( pRetArray, pMatch ); } hb_itemRelease( pMatch ); hb_itemReturnRelease( pRetArray ); fResult = HB_TRUE; break; case 4: /* results AND positions */ pRetArray = hb_itemArrayNew( iMatches ); for( i = 0; i < iMatches; i++ ) { int iSO = HB_REGMATCH_SO( aMatches, i ), iEO = HB_REGMATCH_EO( aMatches, i ); pMatch = hb_arrayGetItemPtr( pRetArray, i + 1 ); hb_arrayNew( pMatch, 3 ); if( iEO != -1 ) { /* matched string */ hb_arraySetCL( pMatch, 1, pszString + iSO, iEO - iSO ); /* begin of match */ hb_arraySetNS( pMatch, 2, iSO + 1 ); /* End of match */ hb_arraySetNS( pMatch, 3, iEO ); } else { hb_arraySetCL( pMatch, 1, NULL, 0 ); hb_arraySetNS( pMatch, 2, 0 ); hb_arraySetNS( pMatch, 3, 0 ); } } hb_itemReturnRelease( pRetArray ); fResult = HB_TRUE; break; case 5: /* _ALL_ results AND positions */ { PHB_ITEM pAtxArray; int iMax = hb_parni( 5 ); /* max nuber of matches I want, 0 = unlimited */ int iGetMatch = hb_parni( 6 ); /* Gets if want only one single match or a sub-match */ HB_BOOL fOnlyMatch = hb_parldef( 7, 1 ); /* if HB_TRUE returns only matches and sub-matches, not positions */ HB_SIZE nOffset = 0; int iCount = 0; int iSO, iEO; /* Set new array */ pRetArray = hb_itemArrayNew( 0 ); do { /* If I want all matches */ if( iGetMatch == 0 || /* Check boundaries */ ( iGetMatch < 0 || iGetMatch > iMatches ) ) { pAtxArray = hb_itemArrayNew( iMatches ); for( i = 0; i < iMatches; i++ ) { iSO = HB_REGMATCH_SO( aMatches, i ); iEO = HB_REGMATCH_EO( aMatches, i ); pMatch = hb_arrayGetItemPtr( pAtxArray, i + 1 ); if( ! fOnlyMatch ) { hb_arrayNew( pMatch, 3 ); if( iEO != -1 ) { /* matched string */ hb_arraySetCL( pMatch, 1, pszString + iSO, iEO - iSO ); /* begin of match */ hb_arraySetNS( pMatch, 2, nOffset + iSO + 1 ); /* End of match */ hb_arraySetNS( pMatch, 3, nOffset + iEO ); } else { hb_arraySetCL( pMatch, 1, NULL, 0 ); hb_arraySetNS( pMatch, 2, 0 ); hb_arraySetNS( pMatch, 3, 0 ); } } else { if( iEO != -1 ) /* matched string */ hb_itemPutCL( pMatch, pszString + iSO, iEO - iSO ); else hb_itemPutC( pMatch, NULL ); } } hb_arrayAddForward( pRetArray, pAtxArray ); hb_itemRelease( pAtxArray ); } else /* Here I get only single matches */ { i = iGetMatch - 1; iSO = HB_REGMATCH_SO( aMatches, i ); iEO = HB_REGMATCH_EO( aMatches, i ); pMatch = hb_itemNew( NULL ); if( ! fOnlyMatch ) { hb_arrayNew( pMatch, 3 ); if( iEO != -1 ) { /* matched string */ hb_arraySetCL( pMatch, 1, pszString + iSO, iEO - iSO ); /* begin of match */ hb_arraySetNS( pMatch, 2, nOffset + iSO + 1 ); /* End of match */ hb_arraySetNS( pMatch, 3, nOffset + iEO ); } else { hb_arraySetCL( pMatch, 1, NULL, 0 ); hb_arraySetNS( pMatch, 2, 0 ); hb_arraySetNS( pMatch, 3, 0 ); } } else { if( iEO != -1 ) /* matched string */ hb_itemPutCL( pMatch, pszString + iSO, iEO - iSO ); else hb_itemPutC( pMatch, NULL ); } hb_arrayAddForward( pRetArray, pMatch ); hb_itemRelease( pMatch ); } iEO = HB_REGMATCH_EO( aMatches, 0 ); if( iEO == -1 ) break; nLen -= iEO; pszString += iEO; nOffset += iEO; iCount++; } while( iEO && nLen && ( iMax == 0 || iCount < iMax ) && ( iMatches = hb_regexec( pRegEx, pszString, nLen, iMaxMatch, aMatches ) ) > 0 ); hb_itemReturnRelease( pRetArray ); fResult = HB_TRUE; break; } } } else if( iRequest == 3 ) { pRetArray = hb_itemArrayNew( 1 ); hb_arraySet( pRetArray, 1, pString ); hb_itemReturnRelease( pRetArray ); fResult = HB_TRUE; } hb_regexFree( pRegEx ); return fResult; }
static const char * _hb_jsonDecode( const char * szSource, PHB_ITEM pValue ) { if( *szSource == '\"' ) { char * szDest, * szHead; HB_SIZE nAlloc = 16; szHead = szDest = ( char * ) hb_xgrab( nAlloc ); szSource++; while( *szSource != '\"' ) { if( szHead + 6 >= szDest + nAlloc ) { HB_SIZE nLen = szHead - szDest; nAlloc += nAlloc << 1; szDest = ( char * ) hb_xrealloc( szDest, nAlloc ); szHead = szDest + nLen; } if( *szSource == '\\' ) { szSource++; switch( *szSource ) { case '\"': *szHead++ = '\"'; break; case '\\': *szHead++ = '\\'; break; case '/': *szHead++ = '/'; break; case 'b': *szHead++ = '\b'; break; case 'f': *szHead++ = '\f'; break; case 'n': *szHead++ = '\n'; break; case 'r': *szHead++ = '\r'; break; case 't': *szHead++ = '\t'; break; case 'u': { HB_WCHAR wc = 0; int i; for( i = 0; i < 4; i++ ) { char c = *++szSource; wc <<= 4; if( c >= '0' && c <= '9' ) wc += c - '0'; else if( c >= 'A' && c <= 'F' ) wc += c - 'A' + 10; else if( c >= 'a' && c <= 'f' ) wc += c - 'a' + 10; else { hb_xfree( szDest ); return NULL; } } szHead += hb_cdpU16ToStr( hb_vmCDP(), HB_CDP_ENDIAN_NATIVE, &wc, 1, szHead, szDest + nAlloc - szHead ); break; } default: hb_xfree( szDest ); return NULL; } szSource++; } else if( *( const unsigned char * ) szSource >= ' ' ) *szHead++ = *szSource++; else { hb_xfree( szDest ); return NULL; } } hb_itemPutCL( pValue, szDest, szHead - szDest ); hb_xfree( szDest ); return szSource + 1; } else if( *szSource == '-' || ( *szSource >= '0' && *szSource <= '9' ) ) { /* NOTE: this function is much less strict to number format than JSON syntax definition. This is allowed behaviour [Mindaugas] */ HB_MAXINT nValue = 0; double dblValue = 0; HB_BOOL fNeg, fDbl = HB_FALSE; int iDec = 0; fNeg = *szSource == '-'; if( fNeg ) szSource++; while( *szSource >= '0' && *szSource <= '9' ) { nValue = nValue * 10 + *szSource - '0'; szSource++; } if( *szSource == '.' ) { double mult = 1; dblValue = ( double ) nValue; fDbl = HB_TRUE; szSource++; while( *szSource >= '0' && *szSource <= '9' ) { mult /= 10; dblValue += ( ( double ) ( *szSource - '0' ) ) * mult; szSource++; iDec++; } } if( *szSource == 'e' || *szSource == 'E' ) { HB_BOOL fNegExp; int iExp = 0; szSource++; fNegExp = *szSource == '-'; if( fNegExp ) szSource++; while( *szSource >= '0' && *szSource <= '9' ) { iExp = iExp * 10 + *szSource - '0'; szSource++; } if( ! fDbl ) { dblValue = ( double ) nValue; fDbl = HB_TRUE; } if( fNegExp ) iDec += iExp; dblValue = hb_numExpConv( dblValue, fNegExp ? iExp : -iExp ); } if( fDbl ) hb_itemPutNDDec( pValue, hb_numRound( fNeg ? -dblValue : dblValue, iDec ), iDec ); else hb_itemPutNInt( pValue, fNeg ? -nValue : nValue ); return szSource; } else if( ! strncmp( szSource, "null", 4 ) ) { hb_itemClear( pValue ); return szSource + 4; } else if( ! strncmp( szSource, "true", 4 ) ) { hb_itemPutL( pValue, HB_TRUE ); return szSource + 4; } else if( ! strncmp( szSource, "false", 5 ) ) { hb_itemPutL( pValue, HB_FALSE ); return szSource + 5; } else if( *szSource == '[' ) { hb_arrayNew( pValue, 0 ); szSource = _skipws( szSource + 1 ); if( *szSource != ']' ) { PHB_ITEM pItem = hb_itemNew( NULL ); for( ;; ) { szSource = _hb_jsonDecode( szSource, pItem ); if( ! szSource ) { hb_itemRelease( pItem ); return NULL; } hb_arrayAddForward( pValue, pItem ); szSource = _skipws( szSource ); if( *szSource == ',' ) { szSource = _skipws( szSource + 1 ); continue; } else if( *szSource == ']' ) break; else { hb_itemRelease( pItem ); return NULL; } } hb_itemRelease( pItem ); } return szSource + 1; } else if( *szSource == '{' ) { hb_hashNew( pValue ); szSource = _skipws( szSource + 1 ); if( *szSource != '}' ) { PHB_ITEM pItemKey = hb_itemNew( NULL ); PHB_ITEM pItemValue = hb_itemNew( NULL ); for( ;; ) { /* Do we need to check if key does not exist yet? */ if( ( szSource = _hb_jsonDecode( szSource, pItemKey ) ) == NULL || ! HB_IS_STRING( pItemKey ) || * ( szSource = _skipws( szSource ) ) != ':' || ( szSource = _hb_jsonDecode( _skipws( szSource + 1 ), pItemValue ) ) == NULL) { hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); return NULL; } hb_hashAdd( pValue, pItemKey, pItemValue ); szSource = _skipws( szSource ); if( *szSource == ',' ) { szSource = _skipws( szSource + 1 ); continue; } else if( *szSource == '}' ) break; else { hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); return NULL; } } hb_itemRelease( pItemKey ); hb_itemRelease( pItemValue ); } return szSource + 1; } return NULL; }
HB_EXTERN_END /* adjustable, but this should be sufficient in normal situation */ #define MAX_READ 4096 void hb_ParseLine( PHB_ITEM pReturn, const char * szText, int iDelimiter, int * iWord ) { if( szText ) { int iLen = ( int ) strlen( szText ); if( iLen > 0 ) { HB_ITEM_NEW( Temp ); int i = 0, word_count = 0; /* booked enough memory */ char * szResult = ( char * ) hb_xgrab( iLen + 1 ); while( i < iLen ) { int ui = 0; hb_xmemset( szResult, ' ', ( size_t ) ( iLen + 1 ) ); /* an '"' found, loop until the next one is found */ if( szText[ i ] == '"' ) { /* an '"' after '"' ? */ if( szText[ i + 1 ] != '"' ) szResult[ ui ] = szText[ i + 1 ]; else szResult[ ui ] = '\0'; ++i; while( ++i < iLen ) { if( szText[ i - 1 ] == '"' ) { szResult[ ui + 1 ] = '\0'; break; } if( szText[ i ] == '"' ) szResult[ ui + 1 ] = '\0'; else szResult[ ++ui ] = szText[ i ]; } word_count++; hb_arrayAddForward( pReturn, hb_itemPutC( &Temp, szResult ) ); } /* delimiter found */ else if( szText[ i ] == iDelimiter ) { /* first delimiter found but no word yet */ if( word_count == 0 ) /* add an empty string */ szResult[ ui ] = '\0'; else { /* we have already have the first word * check next character */ if( szText[ i - 1 ] == iDelimiter ) /* delimiter after delimiter * just add an empty string */ szResult[ ui ] = '\0'; else { /* ",,0" * it is not a delimiter * move to next character */ ++i; szResult[ ui ] = szText[ i ]; while( ++i < iLen ) { if( szText[ i ] == iDelimiter ) break; szResult[ ++ui ] = szText[ i ]; } } } word_count++; szResult[ ui + 1 ] = '\0'; hb_arrayAddForward( pReturn, hb_itemPutC( &Temp, szResult ) ); } else { szResult[ ui ] = szText[ i ]; while( ++i < iLen ) { if( szText[ i ] == iDelimiter ) { szResult[ ui + 1 ] = '\0'; break; } if( szText[ i ] == '"' ) { szResult[ ui ] = szText[ i + 1 ]; ++i; while( ++i < iLen ) { if( ( szText[ i - 1 ] == '"' ) || ( szText[ i ] == '"' ) ) { szResult[ ui + 1 ] = '\0'; break; } szResult[ ++ui ] = szText[ i ]; } } else szResult[ ++ui ] = szText[ i ]; } word_count++; szResult[ ui + 1 ] = '\0'; hb_arrayAddForward( pReturn, hb_itemPutC( &Temp, szResult ) ); } i++; } /* last character in passed string is a delimiter * just add an empty string */ if( szText[ iLen - 1 ] == iDelimiter ) { word_count++; hb_arrayAddForward( pReturn, hb_itemPutC( &Temp, "" ) ); } /* store number of words */ *iWord = word_count; /* clean up */ hb_xfree( szResult ); } } }