Locale-Hebrew-1.05/000755 000765 000024 00000000000 11377352513 013627 5ustar00austaff000000 000000 Locale-Hebrew-1.05/bidi.c000644 000765 000024 00000124417 10122634032 014675 0ustar00austaff000000 000000 /* $File: //member/autrijus/Locale-Hebrew/bidi.c $ $Author: autrijus $ $Revision: #3 $ $Change: 11166 $ $DateTime: 2004/09/17 21:16:27 $ */ /* This code is slightly modified from: Bidi.cpp - version 24 Reference implementation for Unicode Bidirectional Algorithm */ #include #define ASSERT(x) if (!(x)) { fprintf(stderr, "assert failed: %s\n", #x); exit(-1);} else ; #define TCHAR unsigned char #ifndef BOOL #define BOOL char #define FALSE 0 #define TRUE 1 #endif /*------------------------------------------------------------------------ File: Bidi.C Description ----------- Sample Implementation of the Unicode Bidirectional Algorithm as it was revised by Revision 5 of the Uniode Technical Report # 9 (1999-8-17) This implementation is organized into several passes, each implemen- ting one or more of the rules of the Unicode Bidi Algorithm. The resolution of Weak Types and of Neutrals each use a state table approach. Both a printf based interface and a Windows DlgProc are provided for interactive testing. The file biditest.cpp contains hooks to link to a stress harness comparing this implementation to a Java based implementation. This harness was used to verify that the two implementations produce identical results. Implementation Note ------------------- NOTE: The Unicode Birdirectional Algorithm removes all explicit formatting codes in rule X9, but states that this can be simulated by conformant implementations. This implementation attempts to demonstrate such a simulation To demonstrate this, the current implementation does the following: in resolveExplicit() - change LRE, LRO, RLE, RLO, PDF to BN - assign nested levels to BN in resolveWeak and resolveNeutrals - assign L and R to BN's where they exist in place of sor and eor by changing the last BN in front of a level change to a strong type - skip over BN's for the purpose of determining actions - include BN in the count of deferred runs which will resolve some of them to EN, AN and N in resolveWhiteSpace - set the level of any surviving BN to the base level, or the level of the preceding character - include LRE,LRO, RLE, RLO, PDF and BN in the count whitespace to be reset This will result in the same order for non-BN characters as if the BN characters had been removed. The clean() function can be used to remove boundary marks for verification purposes. Notation -------- Pointer variables generally start with the letter p Counter variables generally start with the letter c Index variables generally start with the letter i Boolean variables generally start with the letter f The enumerated bidirectional types have the same name as in the description for the Unicode Bidirectional Algorithm Update History: -------------- - clean version for publication - new commandline interface - Last Revised 11-4-99 Disclaimer and legal rights --------------------------- NOTE: This c file is directly based on the C++ file, but has not been exhaustively tested for compliance with the bidi algorithm. We think that the only effect the changes had was to comply with the differences in C++ vs C syntax, but don't take our word for it. This file contains bugs. All representations to the contrary are void. Source code in this file and the header file may be distributed free of charge by anyone, as long as full credit is given and any and all liabilities are assumed by the recipient. Written by: Asmus Freytag C++ and Windows dependencies removed, and command line interface added by: Rick McGowan Copyright (C) 1999, ASMUS, Inc. All Rights Reserved ------------------------------------------------------------------------*/ // === HELPER FUNCTIONS AND DECLARATIONS ================================= #define odd(x) ((x) & 1) /*------------------------------------------------------------------------ Bidirectional Character Types as defined by the Unicode Bidirectional Algorithm Table 3-7. Note: The list of bidirectional character types here is not grouped the same way as the table 3-7, since the numeric values for the types are chosen to keep the state and action tables compact. ------------------------------------------------------------------------*/ enum { // input types // ON MUST be zero, code relies on ON = N = 0 ON = 0, // Other Neutral L, // Left Letter R, // Right Letter AN, // Arabic Number EN, // European Number AL, // Arabic Letter (Right-to-left) NSM, // Non-spacing Mark CS, // Common Separator ES, // European Separator ET, // European Terminator (post/prefix e.g. $ and %) // resolved types BN, // Boundary neutral (type of RLE etc after explicit levels) // input types, S, // Segment Separator (TAB) // used only in L1 WS, // White space // used only in L1 B, // Paragraph Separator (aka as PS) // types for explicit controls RLO, // these are used only in X1-X9 RLE, LRO, LRE, PDF, // resolved types, also resolved directions N = ON, // alias, where ON, WS and S are treated the same }; /*---------------------------------------------------------------------- The following array maps character codes to types for the purpose of this sample implementation. The legend string gives a human readable explanation of the pseudo alphabet. For simplicity, characters entered by buttons are given a 1:1 mapping between their type and pseudo character value. Pseudo characters that can be typed from the keyboard are explained in the legend string. Use the Unicode Character Database for the real values in real use. ---------------------------------------------------------------------*/ #define LRM 4 #define RLM 5 #define LS 0x13 int TypesFromChar[] = { //0 1 2 3 4 5 6 7 8 9 a b c d e f ON, ON, ON, ON, ON, ON, ON, ON, ON, S, ON, ON, ON, ON, ON, ON, /*00-0f*/ ON,ON,ON,ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, /*10-1f*/ WS, ON, ON, ON, ET, ET, ON, ON, ON, ON, ON, ON, CS, ON, CS, CS, /*20-2f*/ EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, CS, ON, ON, ON, ON, ON, /*30-3f*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, /*40-4f*/ L, L, L, L, L, L, L, L, L, L, L, ON, B, ON, ON, ON, /*50-5f*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, /*60-6f*/ L, L, L, L, L, L, L, L, L, L, L, ON, S, ON, ON, ON, /*70-7f*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*80-8f*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*90-9f*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*a0-af*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*b0-bf*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*c0-cf*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON,ON, ON, ON, /*d0-df*/ R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, /*e0-ef*/ R, R, R, R, R, R, R, R, R, R, R, ON, ON,ON, ON, ON, /*f0-ff*/ }; // WS, LS and S are not explicitly needed except for L1. Therefore this // Table conflates ON, S, WS, and LS to N, all others unchanged int NTypes[] = { N, // ON, L, // L, R, // R, AN, // AN, EN, // EN, AL, // AL NSM, // NSM CS, // CS ES, // ES ET, // ET BN, // BN N, // S N, // WS B, // B RLO, // RLO RLE, // RLE LRO, // LRO LRE, // LRE PDF, // PDF ON, // LS }; int ClassFromChN(TCHAR ch) { /* ASSERT(ch < 0x7f && ch >= 0);*/ return NTypes[TypesFromChar[ch]]; } int ClassFromChWS(TCHAR ch) { /* ASSERT(ch < 0x7f && ch >= 0);*/ return TypesFromChar[ch]; } // === DISPLAY SUPPORT ================================================= enum // Display character codes { RIGHT = '<', // rtl arrow LEFT = '>', // ltr arrow PUSH = '+', // dn arrow POP = '-', // up arrow LSEP = '=', // double dagger NEUTRAL = ' ', // rtl/ltr dbl headed arrow ALPHA = 'a', }; // display support: TCHAR CharFromTypes[] = { NEUTRAL, // ON, LEFT, // L, RIGHT, // R, '9', // AN, '1', // EN, ALPHA, // AL '@', // NSM '.', // CS ',', // ES '$', // ET ':', // BN 'X', // S '_', // WS 'B', // B PUSH, // RLO PUSH, // RLE PUSH, // LRO PUSH, // LRE POP, // PDF LSEP, // LS }; // This works only for testing // a full implementation would need 61 levels.... int CharFromLevel[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'X', 'Y', 'Z' // overhang levels }; // === HELPER FUNCTIONS ================================================ // reverse cch characters void reverse(TCHAR *psz, int cch) { int ich; TCHAR chTemp; for (ich = 0; ich < --cch; ich++) { chTemp = psz[ich]; psz[ich] = psz[cch]; psz[cch] = chTemp; } } // Set a run of cval values at locations all prior to, but not including // iStart, to the new value nval. void SetDeferredRun(int *pval, int cval, int iStart, int nval) { int i; for (i = iStart - 1; i >= iStart - cval; i--) { pval[i] = nval; } } // === ASSIGNING BIDI CLASSES ============================================ /*------------------------------------------------------------------------ Function: classify Determines the character classes for all following passes of the algorithm Input: Text string Character count Whether to report types as WS, ON, S or as N (FALSE) Output: Array of directional classes ------------------------------------------------------------------------*/ int classify(const TCHAR *pszText, int * pcls, int cch, BOOL fWS) { int ich; if (fWS) { for (ich = 0; ich < cch; ich++) { pcls[ich] = ClassFromChWS(pszText[ich]); } return ich; } else { for (ich = 0; ich < cch; ich++) { pcls[ich] = ClassFromChN(pszText[ich]); } return ich; } } // === THE PARAGRAPH LEVEL =============================================== /*------------------------------------------------------------------------ Function: resolveParagraphs Resolves the input strings into blocks over which the algorithm is then applied. Implements Rule P1 of the Unicode Bidi Algorithm Input: Text string Character count Output: revised character count Note: This is a very simplistic function. In effect it restricts the action of the algorithm to the first paragraph in the input where a paragraph ends at the end of the first block separator or at the end of the input text. ------------------------------------------------------------------------*/ int resolveParagraphs(int * types, int cch) { int ich; // skip characters not of type B for (ich = 0; ich < cch && types[ich] != B; ich++) ; // stop after first B, make it a BN for use in the next steps if (ich < cch && types[ich] == B) types[ich++] = BN; return ich; } /*------------------------------------------------------------------------ Function: baseLevel Determines the base level Implements rule P2 of the Unicode Bidi Algorithm. Input: Array of directional classes Character count Note: Ignores explicit embeddings ------------------------------------------------------------------------*/ int baseLevel(const int * pcls, int cch) { int ich; for (ich = 0; ich < cch; ich++) { switch (pcls[ich]) { // strong left case L: return 0; break; // strong right case R: case AL: return 1; break; } } return 0; } //====== RESOLVE EXPLICIT ================================================ int GreaterEven(int i) { return odd(i) ? i + 1 : i + 2; } int GreaterOdd(int i) { return odd(i) ? i + 2 : i + 1; } int EmbeddingDirection(int level) { return odd(level) ? R : L; } /*------------------------------------------------------------------------ Function: resolveExplicit Recursively resolves explicit embedding levels and overrides. Implements rules X1-X9, of the Unicode Bidirectional Algorithm. Input: Base embedding level and direction Character count Output: Array of embedding levels In/Out: Array of direction classes Note: The function uses two simple counters to keep track of matching explicit codes and PDF. Use the default argument for the outermost call. The nesting counter counts the recursion depth and not the embedding level. ------------------------------------------------------------------------*/ const int MAX_LEVEL = 61; // the real value int resolveExplicit(int level, int dir, int * pcls, int * plevel, int cch, int nNest) { // always called with a valid nesting level // nesting levels are != embedding levels int nLastValid = nNest; int ich, cls; // check input values ASSERT(nNest >= 0 && level >= 0 && level <= MAX_LEVEL); // process the text for (ich = 0; ich < cch; ich++) { cls = pcls[ich]; switch (cls) { case LRO: case LRE: nNest++; if (GreaterEven(level) <= MAX_LEVEL) { plevel[ich] = GreaterEven(level); pcls[ich] = BN; ich += resolveExplicit(plevel[ich], (cls == LRE ? N : L), &pcls [ich+1], &plevel[ich+1], cch - (ich+1), nNest); nNest--; continue; } cls = pcls[ich] = BN; break; case RLO: case RLE: nNest++; if (GreaterOdd(level) <= MAX_LEVEL) { plevel[ich] = GreaterOdd(level); pcls[ich] = BN; ich += resolveExplicit(plevel[ich], (cls == RLE ? N : R), &pcls [ich+1], &plevel[ich+1], cch - (ich+1), nNest); nNest--; continue; } cls = pcls[ich] = BN; break; case PDF: cls = pcls[ich] = BN; if (nNest) { if (nLastValid < nNest) { nNest--; } else { cch = ich; // break the loop, but complete body } } } // Apply the override if (dir != N) { cls = dir; } plevel[ich] = level; if (pcls[ich] != BN) { pcls[ich] = cls; } } return ich; } // === RESOLVE WEAK TYPES ================================================ enum // possible states { xa, // arabic letter xr, // right leter xl, // left letter ao, // arabic lett. foll by ON ro, // right lett. foll by ON lo, // left lett. foll by ON rt, // ET following R lt, // ET following L cn, // EN, AN following AL ra, // arabic number foll R re, // european number foll R la, // arabic number foll L le, // european number foll L ac, // CS following cn rc, // CS following ra rs, // CS,ES following re lc, // CS following la ls, // CS,ES following le ret, // ET following re let, // ET following le } ; int stateWeak[20][10] = { // N, L, R AN, EN, AL,NSM, CS, ES, ET, /*xa*/ ao, xl, xr, cn, cn, xa, xa, ao, ao, ao, /* arabic letter */ /*xr*/ ro, xl, xr, ra, re, xa, xr, ro, ro, rt, /* right leter */ /*xl*/ lo, xl, xr, la, le, xa, xl, lo, lo, lt, /* left letter */ /*ao*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* arabic lett. foll by ON*/ /*ro*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* right lett. foll by ON */ /*lo*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* left lett. foll by ON */ /*rt*/ ro, xl, xr, ra, re, xa, rt, ro, ro, rt, /* ET following R */ /*lt*/ lo, xl, xr, la, le, xa, lt, lo, lo, lt, /* ET following L */ /*cn*/ ao, xl, xr, cn, cn, xa, cn, ac, ao, ao, /* EN, AN following AL */ /*ra*/ ro, xl, xr, ra, re, xa, ra, rc, ro, rt, /* arabic number foll R */ /*re*/ ro, xl, xr, ra, re, xa, re, rs, rs,ret, /* european number foll R */ /*la*/ lo, xl, xr, la, le, xa, la, lc, lo, lt, /* arabic number foll L */ /*le*/ lo, xl, xr, la, le, xa, le, ls, ls,let, /* european number foll L */ /*ac*/ ao, xl, xr, cn, cn, xa, ao, ao, ao, ao, /* CS following cn */ /*rc*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS following ra */ /*rs*/ ro, xl, xr, ra, re, xa, ro, ro, ro, rt, /* CS,ES following re */ /*lc*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS following la */ /*ls*/ lo, xl, xr, la, le, xa, lo, lo, lo, lt, /* CS,ES following le */ /*ret*/ ro, xl, xr, ra, re, xa,ret, ro, ro,ret, /* ET following re */ /*let*/ lo, xl, xr, la, le, xa,let, lo, lo,let /* ET following le */ }; enum { // possible actions // primitives IX = 0x100, // increment XX = 0xF, // no-op // actions xxx = (XX << 4) + XX, // no-op xIx = IX + xxx, // increment run xxN = (XX << 4) + ON, // set current to N xxE = (XX << 4) + EN, // set current to EN xxA = (XX << 4) + AN, // set current to AN xxR = (XX << 4) + R, // set current to R xxL = (XX << 4) + L, // set current to L Nxx = (ON << 4) + 0xF, // set run to neutral Axx = (AN << 4) + 0xF, // set run to AN ExE = (EN << 4) + EN, // set run to EN, set current to EN NIx = (ON << 4) + 0xF + IX, // set run to N, increment NxN = (ON << 4) + ON, // set run to N, set current to N NxR = (ON << 4) + R, // set run to N, set current to R NxE = (ON << 4) + EN, // set run to N, set current to EN AxA = (AN << 4) + AN, // set run to AN, set current to AN NxL = (ON << 4) + L, // set run to N, set current to L LxL = (L << 4) + L, // set run to L, set current to L }; int actionWeak[20][10] = { // N, L, R AN, EN, AL, NSM, CS, ES, ET, /*xa*/ xxx, xxx, xxx, xxx, xxA, xxR, xxR, xxN, xxN, xxN, /* arabic letter */ /*xr*/ xxx, xxx, xxx, xxx, xxE, xxR, xxR, xxN, xxN, xIx, /* right leter */ /*xl*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xIx, /* left letter */ /*ao*/ xxx, xxx, xxx, xxx, xxA, xxR, xxN, xxN, xxN, xxN, /* arabic lett. foll b y ON */ /*ro*/ xxx, xxx, xxx, xxx, xxE, xxR, xxN, xxN, xxN, xIx, /* right lett. foll by ON */ /*lo*/ xxx, xxx, xxx, xxx, xxL, xxR, xxN, xxN, xxN, xIx, /* left lett. foll by ON */ /*rt*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, xIx, NxN, NxN, xIx, /* ET following R */ /*lt*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, xIx, NxN, NxN, xIx, /* ET following L */ /*cn*/ xxx, xxx, xxx, xxx, xxA, xxR, xxA, xIx, xxN, xxN, /* EN, AN following A L */ /*ra*/ xxx, xxx, xxx, xxx, xxE, xxR, xxA, xIx, xxN, xIx, /* arabic number foll R */ /*re*/ xxx, xxx, xxx, xxx, xxE, xxR, xxE, xIx, xIx, xxE, /* european number fol l R */ /*la*/ xxx, xxx, xxx, xxx, xxL, xxR, xxA, xIx, xxN, xIx, /* arabic number foll L */ /*le*/ xxx, xxx, xxx, xxx, xxL, xxR, xxL, xIx, xIx, xxL, /* european number fol l L */ /*ac*/ Nxx, Nxx, Nxx, Axx, AxA, NxR, NxN, NxN, NxN, NxN, /* CS following cn */ /*rc*/ Nxx, Nxx, Nxx, Axx, NxE, NxR, NxN, NxN, NxN, NIx, /* CS following ra */ /*rs*/ Nxx, Nxx, Nxx, Nxx, ExE, NxR, NxN, NxN, NxN, NIx, /* CS,ES following re */ /*lc*/ Nxx, Nxx, Nxx, Axx, NxL, NxR, NxN, NxN, NxN, NIx, /* CS following la */ /*ls*/ Nxx, Nxx, Nxx, Nxx, LxL, NxR, NxN, NxN, NxN, NIx, /* CS,ES following le */ /*ret*/xxx, xxx, xxx, xxx, xxE, xxR, xxE, xxN, xxN, xxE, /* ET following re */ /*let*/xxx, xxx, xxx, xxx, xxL, xxR, xxL, xxN, xxN, xxL /* ET following le */ }; static inline int GetDeferredType(int action) { return (action >> 4) & 0xF; } static inline int GetResolvedType(int action) { return action & 0xF; } /* Note on action table: States can be of two kinds: - Immediate Resolution State, where each input token is resolved as soon as it is seen. These states havve only single action codes (xxN) or the no-op (xxx) for static input tokens. - Deferred Resolution State, where input tokens either either extend the run (xIx) or resolve its Type (e.g. Nxx). Input classes are of three kinds - Static Input Token, where the class of the token remains unchanged on output (AN, L, N, R) - Replaced Input Token, where the class of the token is always replaced on output (AL, BN, NSM, CS, ES, ET) - Conditional Input Token, where the class of the token is changed on output in some, but not all, cases (EN) Where tokens are subject to change, a double action (e.g. NxA, or NxN) is _required_ after deferred states, resolving both the deferred state and changing the current token. These properties of the table are verified by assertions below. This code is needed only during debugging and maintenance */ /*------------------------------------------------------------------------ Function: resolveWeak Resolves the directionality of numeric and other weak character types Implements rules W1-W7 of the Unicode Bidirectional Algorithm. Input: Array of embedding levels Character count In/Out: Array of directional classes Note: On input only these directional classes are expected AL, HL, R, L, ON, BN, NSM, AN, EN, ES, ET, CS, ------------------------------------------------------------------------*/ void resolveWeak(int baselevel, int *pcls, int *plevel, int cch) { int state = odd(baselevel) ? xr : xl; int cls, ich, action; int level = baselevel; int cchRun = 0; int clsRun, clsNew; for (ich = 0; ich < cch; ich++) { // ignore boundary neutrals if (pcls[ich] == BN) { // must flatten levels unless at a level change; plevel[ich] = level; // lookahead for level changes if (ich + 1 == cch && level != baselevel) { // have to fixup last BN before end of the loop, since // its fix-upped value will be needed below the assert pcls[ich] = EmbeddingDirection(level); } else if (ich + 1 < cch && level != plevel[ich+1] && pcls[ich+1] != BN) { // fixup LAST BN in front / after a level run to make // it act like the SOR/EOR in rule X10 int newlevel = plevel[ich+1]; if (level > newlevel) { newlevel = level; } plevel[ich] = newlevel; // must match assigned level pcls[ich] = EmbeddingDirection(newlevel); level = plevel[ich+1]; } else { // don't interrupt runs if (cchRun) { cchRun++; } continue; } } ASSERT(pcls[ich] <= BN); cls = pcls[ich]; action = actionWeak[state][cls]; // resolve the directionality for deferred runs clsRun = GetDeferredType(action); if (clsRun != XX) { SetDeferredRun(pcls, cchRun, ich, clsRun); cchRun = 0; } // resolve the directionality class at the current location clsNew = GetResolvedType(action); if (clsNew != XX) { pcls[ich] = clsNew; } // increment a deferred run if (IX & action) { cchRun++; } state = stateWeak[state][cls]; } // resolve any deferred runs // use the direction of the current level to emulate PDF cls = EmbeddingDirection(level); // resolve the directionality for deferred runs clsRun = GetDeferredType(actionWeak[state][cls]); if (clsRun != XX) { SetDeferredRun(pcls, cchRun, ich, clsRun); } } // === RESOLVE NEUTRAL TYPES ============================================== // action values enum { // action to resolve previous input nL = L, // resolve EN to L En = 3 << 4, // resolve neutrals run to embedding level direction Rn = R << 4, // resolve neutrals run to strong right Ln = L << 4, // resolved neutrals run to strong left In = (1<<8), // increment count of deferred neutrals LnL = (1<<4)+L, // set run and EN to L }; int GetDeferredNeutrals(int action, int level) { action = (action >> 4) & 0xF; if (action == (En >> 4)) { return EmbeddingDirection(level); } else { return action; } } int GetResolvedNeutrals(int action) { action = action & 0xF; if (action == In) { return 0; } else { return action; } } // state values enum { // new temporary class r, // R and characters resolved to R l, // L and characters resolved to L rn, // N preceded by right ln, // N preceded by left a, // AN preceded by left (the abbrev 'la' is used up above) na, // N preceeded by a }; /*------------------------------------------------------------------------ Notes: By rule W7, whenever a EN is 'dominated' by an L (including start of run with embedding direction = L) it is resolved to, and further treated as L. This leads to the need for 'a' and 'na' states. ------------------------------------------------------------------------*/ int actionNeutrals[6][5] = { // N, L, R, AN, EN, = cls // state = In, 0, 0, 0, 0, // r right In, 0, 0, 0, L, // l left In, En, Rn, Rn, Rn, // rn N preceded by right In, Ln, En, En, LnL,// ln N preceded by left In, 0, 0, 0, L, // a AN preceded by left In, En, Rn, Rn, En // na N preceded by a }; int stateNeutrals[6][5] = { // N, L, R, AN, EN = cls // state = rn, l, r, r, r, // r right ln, l, r, a, l, // l left rn, l, r, r, r, // rn N preceded by right ln, l, r, a, l, // ln N preceded by left na, l, r, a, l, // a AN preceded by left na, l, r, a, l // na N preceded by la }; /*------------------------------------------------------------------------ Function: resolveNeutrals Resolves the directionality of neutral character types. Implements rules W7, N1 and N2 of the Unicode Bidi Algorithm. Input: Array of embedding levels Character count Baselevel In/Out: Array of directional classes Note: On input only these directional classes are expected R, L, N, AN, EN and BN W8 resolves a number of ENs to L ------------------------------------------------------------------------*/ void resolveNeutrals(int baselevel, int *pcls, const int *plevel, int cch) { // the state at the start of text depends on the base level int state = odd(baselevel) ? r : l; int cls, ich; int cchRun = 0; int level = baselevel; int action, clsNew, clsRun; for (ich = 0; ich < cch; ich++) { // ignore boundary neutrals if (pcls[ich] == BN) { // include in the count for a deferred run if (cchRun) cchRun++; // skip any further processing continue; } ASSERT(pcls[ich] < 5); // "Only N, L, R, AN, EN are allowed" cls = pcls[ich]; action = actionNeutrals[state][cls]; // resolve the directionality for deferred runs clsRun = GetDeferredNeutrals(action, level); if (clsRun != N) { SetDeferredRun(pcls, cchRun, ich, clsRun); cchRun = 0; } // resolve the directionality class at the current location clsNew = GetResolvedNeutrals(action); if (clsNew != N) pcls[ich] = clsNew; if (In & action) cchRun++; state = stateNeutrals[state][cls]; level = plevel[ich]; } // resolve any deferred runs cls = EmbeddingDirection(level); // eor has type of current level // resolve the directionality for deferred runs clsRun = GetDeferredNeutrals(actionNeutrals[state][cls], level); if (clsRun != N) SetDeferredRun(pcls, cchRun, ich, clsRun); } // === RESOLVE IMPLICIT ================================================= /*------------------------------------------------------------------------ Function: resolveImplicit Recursively resolves implicit embedding levels. Implements rules I1 and I2 of the Unicode Bidirectional Algorithm. Input: Array of direction classes Character count Base level In/Out: Array of embedding levels Note: levels may exceed 15 on output. Accepted subset of direction classes R, L, AN, EN ------------------------------------------------------------------------*/ int addLevel[2][4] = { // L, R, AN, EN = cls // level = /* even */ 0, 1, 2, 2, // EVEN /* odd */ 1, 0, 1, 1, // ODD }; void resolveImplicit(const int * pcls, int * plevel, int cch) { int ich; for (ich = 0; ich < cch; ich++) { // cannot resolve bn here, since some bn were resolved to strong // types in resolveWeak. To remove these we need the original // types, which are available again in resolveWhiteSpace if (pcls[ich] == BN) { continue; } ASSERT(pcls[ich] > 0); // "No Neutrals allowed to survive here." ASSERT(pcls[ich] < 5); // "Out of range." plevel[ich] += addLevel[odd(plevel[ich])][pcls[ich] - 1]; } } // === REORDER =========================================================== /*------------------------------------------------------------------------ Function: resolveLines Breaks a paragraph into lines Input: Character count In/Out: Array of characters Array of line break flags Returns the count of characters on the first line Note: This function only breaks lines at hard line breaks. Other line breaks can be passed in. If pbrk[n] is TRUE, then a break occurs after the character in pszInput[n]. Breaks before the first character are not allowed. ------------------------------------------------------------------------*/ int resolveLines(TCHAR *pszInput, BOOL * pbrk, int cch) { int ich; // skip characters not of type LS for(ich = 0; ich < cch; ich++) { if (pszInput[ich] == LS || (pbrk && pbrk[ich])) { ich++; break; } } return ich; } /*------------------------------------------------------------------------ Function: resolveWhiteSpace Resolves levels for WS and S Implements rule L1 of the Unicode bidi Algorithm. Input: Base embedding level Character count Array of direction classes (for one line of text) In/Out: Array of embedding levels (for one line of text) Note: this should be applied a line at a time. The default driver code supplied in this file assumes a single line of text; for a real implementation, cch and the initial pointer values would have to be adjusted. ------------------------------------------------------------------------*/ void resolveWhitespace(int baselevel, const int *pcls, int *plevel, int cch) { int clevel = 0; int oldlevel = baselevel; int ich; for (ich = 0; ich < cch; ich++) { switch(pcls[ich]) { default: clevel = 0; // any other character breaks the run break; case WS: clevel++; break; case RLE: case LRE: case LRO: case RLO: case PDF: case BN: plevel[ich] = oldlevel; clevel++; break; case S: case B: // reset levels for WS before eot SetDeferredRun(plevel, clevel, ich, baselevel); clevel = 0; plevel[ich] = baselevel; break; } oldlevel = plevel[ich]; } // reset level before eot SetDeferredRun(plevel, clevel, ich, baselevel); } /*------------------------------------------------------------------------ Functions: reorder/reorderLevel Recursively reorders the display string "From the highest level down, reverse all characters at that level and higher, down to the lowest odd level" Implements rule L2 of the Unicode bidi Algorithm. Input: Array of embedding levels Character count Flag enabling reversal (set to FALSE by initial caller) In/Out: Text to reorder Note: levels may exceed 15 resp. 61 on input. Rule L3 - reorder combining marks is not implemented here Rule L4 - glyph mirroring is implemented as a display option below Note: this should be applied a line at a time -------------------------------------------------------------------------*/ int reorderLevel(int level, TCHAR *pszText, const int * plevel, int cch, BOOL fReverse) { int ich; // TRUE as soon as first odd level encountered fReverse = fReverse || odd(level); for (ich = 0; ich < cch; ich++) { if (plevel[ich] < level) { break; } else if (plevel[ich] > level) { ich += reorderLevel(level + 1, pszText + ich, plevel + ich, cch - ich, fReverse) - 1; } } if (fReverse) { reverse(pszText, ich); } return ich; } int reorder(int baselevel, TCHAR *pszText, const int * plevel, int cch) { int ich = 0; while (ich < cch) { ich += reorderLevel(baselevel, pszText + ich, plevel + ich, cch - ich, FALSE); } return ich; } // === DISPLAY OPTIONS ================================================ /*----------------------------------------------------------------------- Function: mirror Crudely implements rule L4 of the Unicode Bidirectional Algorithm Demonstrate mirrored brackets, braces and parens Input: Array of levels Count of characters In/Out: Array of characters (should be array of glyph ids) Note; A full implementation would need to substitute mirrored glyphs even for characters that are not paired (e.g. integral sign). -----------------------------------------------------------------------*/ void mirror(TCHAR *pszInput, const int * plevel, int cch) { int ich; for (ich = 0; ich < cch; ich ++) { if (!odd(plevel[ich])) continue; if (pszInput[ich] == '[') { pszInput[ich] = ']'; } else if (pszInput[ich] == ']') { pszInput[ich] = '['; } else if (pszInput[ich] == '{') { pszInput[ich] = '}'; } else if (pszInput[ich] == '}') { pszInput[ich] = '{'; } else if (pszInput[ich] == ')') { pszInput[ich] = '('; } else if (pszInput[ich] == '(') { pszInput[ich] = ')'; } } } /*----------------------------------------------------------------------- Function: clean remove formatting codes In/Out: Array of characters Count of characters Note; This function can be used to remove formatting codes so the ordering of the string can be compared to implementations that remove formatting codes. This implementation is limited to the pseudo alphabet used for the demo version. -----------------------------------------------------------------------*/ int clean(TCHAR *pszInput, int cch) { int cchMove = 0; int ich; for (ich = 0; ich < cch; ich ++) { if (pszInput[ich] < 0x20) { cchMove++; } else { pszInput[ich - cchMove] = pszInput[ich]; } } pszInput[ich - cchMove] = 0; return ich - cchMove; } /*------------------------------------------------------------------------ Function: BidiLines Implements the Line-by-Line phases of the Unicode Bidi Algorithm Input: Count of characters flag whether to mirror Inp/Out: Input text Array of character directions Array of levels ------------------------------------------------------------------------*/ void BidiLines(int baselevel, TCHAR *pszLine, int *pclsLine, int *plevelLine, int cchPara, int fMirror, BOOL *pbrk) { int cchLine = 0; do { // break lines at LS cchLine = resolveLines(pszLine, pbrk, cchPara); // resolve whitespace resolveWhitespace(baselevel, pclsLine, plevelLine, cchLine); if (fMirror) { mirror(pszLine, plevelLine, cchLine); } // reorder each line in place reorder(baselevel, pszLine, plevelLine, cchLine); pszLine += cchLine; plevelLine += cchLine; pbrk += pbrk ? cchLine : 0; pclsLine += cchLine; cchPara -= cchLine; } while (cchPara); } // ===== FUNCTIONS FOR COMMAND LINE VERSION ============================== #include #include // An alternate CharFromTypes array may be needed to use the command // line version, #define MAX_CCH 256 void ShowInputTypes(FILE* f, TCHAR * pszInput, int cch) { TCHAR pszTypes[MAX_CCH+1]; int ich; for (ich = 0; ich < cch; ich++) { pszTypes[ich] = CharFromTypes[ClassFromChWS(pszInput[ich])]; } pszTypes[ich] = 0; fprintf(f, pszTypes); } void ShowTypes(FILE* f, int * types, int cch) { TCHAR pszTypes[MAX_CCH+1]; int ich; for (ich = 0; ich < cch; ich++) { pszTypes[ich] = CharFromTypes[types[ich]]; } pszTypes[ich] = 0; fprintf(f, pszTypes); } void ShowLevels(FILE* f, int * levels, int cch) { TCHAR pszLevel[MAX_CCH+1]; int ich; for (ich = 0; ich < cch; ich++) { pszLevel[ich] = CharFromLevel[levels[ich]]; } pszLevel[ich] = 0; fprintf(f, pszLevel); } void usage(char *s) { printf("Usage: %s [-verbose] [-nomirror] [-clean] strings...\n", s); printf("\t-verbose = verbose debugging output.\n"); printf("\t-nomirror = refrain from glyph mirroring.\n"); printf("\t-clean = clean up the result.\n"); printf("\tOptions affect all subsequent arguments.\n"); printf("\tAll other arguments are interpreted as strings to process.\n"); } void bidimain(char *string, int cch) { int realArg = 0; int doMirror = 1; int doClean = 0; int beVerbose = 0; int i, baselevel; int *types; int *levels; FILE* f = stdout; types = calloc(sizeof(int), cch); levels = calloc(sizeof(int), cch); // assign directional types classify(string, types, cch, FALSE); // limit text to first block cch = resolveParagraphs(types, cch); // set base level and compute character types baselevel = baseLevel(types, cch); // resolve explicit resolveExplicit(baselevel, 0, types, levels, cch, 0); // resolve weak resolveWeak(baselevel, types, levels, cch); // resolve neutrals resolveNeutrals(baselevel,types, levels, cch); // resolveImplicit resolveImplicit(types, levels, cch); // assign directional types again, but for WS, S this time classify(string, types, cch, TRUE); BidiLines(baselevel, string, types, levels, cch, doMirror, 0); free(types); free(levels); } /* This code is slightly modified from: Bidi.cpp - version 24 Reference implementation for Unicode Bidirectional Algorithm */ int main(int argc, char **argv) { char s[8192]; if (argc != 2) exit(-1); strcpy(s, argv[1]); bidimain(s, strlen(s)); puts(s); } Locale-Hebrew-1.05/Changes000644 000765 000024 00000001163 11377352377 015133 0ustar00austaff000000 000000 [Changes for 1.05 - 2010-05-27] * Fix MANIFEST.SKIP so the signatures test won't cause bogus fail on Win32. * Adds a "See Also" link to Text::Bidi. (Shlomi Fish) [Changes for 1.04 - 2004-09-18] * Add VERSION to POD; reorder things a bit; fix manifest. * Modernise Makefile.PL a bit. [Changes for 1.03 - 2004-09-17] * Revamped tests. * hebrewflip() is now exported by default. (Oded S. Resnik) * Unicode support for Perl 5.8.1+. (Oded S. Resnik) [Changes for 1.02 - 2003-01-14] * Added README and tests. * Update MANIFEST, since Locale::Hebrew::Calendar is now distributed separately. * main() should be int not void. Locale-Hebrew-1.05/Hebrew.pm000644 000765 000024 00000004175 11377352467 015420 0ustar00austaff000000 000000 package Locale::Hebrew; use 5.005; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); use Exporter; use DynaLoader; use AutoLoader; @ISA = qw(Exporter DynaLoader); @EXPORT = @EXPORT_OK = qw(hebrewflip); $VERSION = '1.05'; __PACKAGE__->bootstrap($VERSION); =head1 NAME Locale::Hebrew - Bidirectional Hebrew support =head1 VERSION This document describes version 1.05 of Locale::Hebrew, released May 27, 2010. =head1 SYNOPSIS use Locale::Hebrew; $visual = hebrewflip($logical); =head1 DESCRIPTION This module is based on code from the Unicode Consortium. The charset on their code was bogus, therefore this module had to work the real charset from scratch. There might have some mistakes, though. One function, C, is exported by default. =head1 NOTES The input string is assumed to be in C encoding by default. On Perl version 5.8.1 and above, this module can handle Unicode strings by transparently encoding and decoding it as C. The return value should still be a Unicode string. =head1 SEE ALSO L, which implements related algorithms based on the C library. =cut sub hebrewflip ($) { if ($] >= 5.008001 and utf8::is_utf8($_[0])) { require Encode; return Encode::decode( 'iso-8859-8', _hebrewflip( Encode::encode('iso-8859-8', $_[0]) ) ); } goto &_hebrewflip; } 1; =head1 ACKNOWLEDGMENTS Lots of help from Raz Information Systems, L. Thanks to Oded S. Resnik for suggesting Unicode support and exporting C by default. =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE is the current maintainer. Ariel Brosh Eschop@cpan.orgE is the original author, now passed away. =head1 COPYRIGHT Copyright 2001, 2002 by Ariel Brosh. Copyright 2003-2010 by Audrey Tang. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut __END__ # Local variables: # c-indentation-style: bsd # c-basic-offset: 4 # indent-tabs-mode: nil # End: # vim: expandtab shiftwidth=4: Locale-Hebrew-1.05/Hebrew.xs000644 000765 000024 00000000775 10122634031 015411 0ustar00austaff000000 000000 /* $File: //member/autrijus/Locale-Hebrew/Hebrew.xs $ $Author: autrijus $ $Revision: #2 $ $Change: 11166 $ $DateTime: 2004/09/17 21:16:27 $ */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif MODULE = Locale::Hebrew PACKAGE = Locale::Hebrew SV * _hebrewflip(s) SV * s CODE: int l; char *src, *dst; SV *r; r = newSVsv(s); src = SvPV(r, l); bidimain(src, l); RETVAL = r; OUTPUT: RETVAL Locale-Hebrew-1.05/inc/000755 000765 000024 00000000000 11377352512 014377 5ustar00austaff000000 000000 Locale-Hebrew-1.05/Makefile.PL000755 000765 000024 00000000313 11377352075 015604 0ustar00austaff000000 000000 #!/usr/bin/perl use Config; use inc::Module::Install; name 'Locale-Hebrew'; all_from 'Hebrew.pm'; makemaker_args( OBJECT=> join(' ', map "$_$Config{obj_ext}", qw(Hebrew bidi)), ); sign; WriteAll; Locale-Hebrew-1.05/MANIFEST000644 000765 000024 00000000617 11377352506 014766 0ustar00austaff000000 000000 bidi.c Changes Hebrew.pm Hebrew.xs inc/Module/Install.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm Makefile.PL MANIFEST MANIFEST.SKIP META.yml Module meta-data (added by MakeMaker) README SIGNATURE t/0-signature.t t/1-basic.t t/2-utf8.t Locale-Hebrew-1.05/MANIFEST.SKIP000644 000765 000024 00000000176 11377351561 015533 0ustar00austaff000000 000000 #defaults ^MANIFEST.bak$ ^Makefile$ ^Makefile.old$ ^blib/ ^pm_to_blib$ ^blibdirs$ ^Hebrew.(?!pm$|xs$).*$ ^bidi.(?!c$).*$ ^dll Locale-Hebrew-1.05/META.yml000644 000765 000024 00000000773 11377352510 015104 0ustar00austaff000000 000000 --- abstract: 'Bidirectional Hebrew support' author: - 'Audrey Tang ' build_requires: ExtUtils::MakeMaker: 6.42 configure_requires: ExtUtils::MakeMaker: 6.42 distribution_type: module generated_by: 'Module::Install version 0.95' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Locale-Hebrew no_index: directory: - inc - t requires: perl: 5.005 resources: license: http://dev.perl.org/licenses/ version: 1.05 Locale-Hebrew-1.05/README000644 000765 000024 00000001447 10122634031 014476 0ustar00austaff000000 000000 # $File: //member/autrijus/Locale-Hebrew/README $ $Author: autrijus $ # $Revision: #2 $ $Change: 11166 $ $DateTime: 2004/09/17 21:16:27 $ This is the README file for Locale::Hebrew, a module implementing bidirectional Hebrew support for Perl. * Installation Locale::Hebrew uses the standard perl module install process: cpansign -v # see SIGNATURE for details perl Makefile.PL make make test make install * Copyright Copyright 2001, 2002 by Ariel Brosh. Copyright 2003 by Autrijus Tang . All rights reserved. You can redistribute and/or modify this bundle under the same terms as Perl itself. See . # Local variables: # c-indentation-style: bsd # c-basic-offset: 4 # indent-tabs-mode: nil # End: # vim: expandtab shiftwidth=4: Locale-Hebrew-1.05/SIGNATURE000644 000765 000024 00000003716 11377352513 015122 0ustar00austaff000000 000000 This file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.61. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 29f543ac8d8857f3b382b10c9b03aecd3020e033 Changes SHA1 3b10b88adfb275defab278496c5da79564943268 Hebrew.pm SHA1 870900166e2f7b9f56019acdbbc56b24467fc823 Hebrew.xs SHA1 3b7ddd9f4e749b68570039df9b6c61f59d96a1d9 MANIFEST SHA1 f54b318e644c2f3432fa464a872e1593fd9b0511 MANIFEST.SKIP SHA1 3fc70b336ea2c42e624bd94848c8c6060449e4a0 META.yml SHA1 33870470e55bc9761557a0e9da76957ea2be741b Makefile.PL SHA1 4b86614dd4eac92ff2f259c9c32badd9645e44fe README SHA1 cc6ded44327f42601c2616e418a6037a35c877ce bidi.c SHA1 1ebec4119486a032a5612a403e8d7b7be973e938 inc/Module/Install.pm SHA1 24038af925a69df41972971356ccce885b0fe2ad inc/Module/Install/Base.pm SHA1 8f96eddfef548c9328457fbb17a121631cda356b inc/Module/Install/Can.pm SHA1 ec29048e48edd9c9c55f9de7b773bd7c904335ad inc/Module/Install/Fetch.pm SHA1 0384525d85d51e99532e3ad8729d870113646d14 inc/Module/Install/Makefile.pm SHA1 38c657de4d91f5a60ff8e6c6f6a5547daf7c4ab2 inc/Module/Install/Metadata.pm SHA1 5c25f1104c0038041e3b93e0660c39171e4caf2b inc/Module/Install/Win32.pm SHA1 94d47349c803c4bd2a9230d25e4db0b6aaf1acd8 inc/Module/Install/WriteAll.pm SHA1 4aeb184c9bed26ab6c3be1ebdb8470c0cb353b1f t/0-signature.t SHA1 58f1588eba68af8d1fe37623808615c79efe1b04 t/1-basic.t SHA1 cad4e3de1e561a681ab7cb7a7f7145fad22f50d6 t/2-utf8.t -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (Darwin) iEYEARECAAYFAkv91UoACgkQtLPdNzw1AaCs7gCgg8tqDfnFsIM2Hvllxu6aIK6e jC8AoJnw6Tinxh4qTGHmxlLbqcWmld8n =lhmq -----END PGP SIGNATURE----- Locale-Hebrew-1.05/t/000755 000765 000024 00000000000 11377352512 014071 5ustar00austaff000000 000000 Locale-Hebrew-1.05/t/0-signature.t000644 000765 000024 00000001705 11377351534 016422 0ustar00austaff000000 000000 #!/usr/bin/perl use strict; use Test::More; if (!$ENV{TEST_SIGNATURE}) { plan skip_all => "Set the environment variable TEST_SIGNATURE to enable this test."; } elsif (!eval { require Module::Signature; 1 }) { plan skip_all => "Next time around, consider installing Module::Signature, ". "so you can verify the integrity of this distribution."; } elsif ( !-e 'SIGNATURE' ) { plan skip_all => "SIGNATURE not found"; } elsif ( -s 'SIGNATURE' == 0 ) { plan skip_all => "SIGNATURE file empty"; } elsif (!eval { require Socket; Socket::inet_aton('pgp.mit.edu') }) { plan skip_all => "Cannot connect to the keyserver to check module ". "signature"; } else { plan tests => 1; } my $ret = Module::Signature::verify(); SKIP: { skip "Module::Signature cannot verify", 1 if $ret eq Module::Signature::CANNOT_VERIFY(); cmp_ok $ret, '==', Module::Signature::SIGNATURE_OK(), "Valid signature"; } Locale-Hebrew-1.05/t/1-basic.t000644 000765 000024 00000000501 10122634032 015454 0ustar00austaff000000 000000 # $File: //member/autrijus/Locale-Hebrew/t/1-basic.t $ $Author: autrijus $ # $Revision: #2 $ $Change: 11166 $ $DateTime: 2004/09/17 21:16:27 $ use Test; BEGIN { plan tests => 3 }; use Locale::Hebrew; ok(Locale::Hebrew->VERSION); ok(defined(&hebrewflip)); ok(hebrewflip('ê"äãó ùì äúð'), scalar reverse 'ê"äãó ùì äúð'); Locale-Hebrew-1.05/t/2-utf8.t000644 000765 000024 00000000524 10122634032 015267 0ustar00austaff000000 000000 # $File: //member/autrijus/Locale-Hebrew/t/2-utf8.t $ $Author: autrijus $ # $Revision: #1 $ $Change: 11166 $ $DateTime: 2004/09/17 21:16:27 $ use Test; BEGIN { plan tests => 1 }; BEGIN { if ($] < 5.008001) { skip(1); exit } } use utf8; use Locale::Hebrew; ok(hebrewflip('ך"הדף של התנ'), scalar reverse 'ך"הדף של התנ'); Locale-Hebrew-1.05/inc/Module/000755 000765 000024 00000000000 11377352512 015624 5ustar00austaff000000 000000 Locale-Hebrew-1.05/inc/Module/Install/000755 000765 000024 00000000000 11377352512 017232 5ustar00austaff000000 000000 Locale-Hebrew-1.05/inc/Module/Install.pm000644 000765 000024 00000026371 11377352510 017577 0ustar00austaff000000 000000 #line 1 package Module::Install; # For any maintainers: # The load order for Module::Install is a bit magic. # It goes something like this... # # IF ( host has Module::Install installed, creating author mode ) { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install # 3. The installed version of inc::Module::Install loads # 4. inc::Module::Install calls "require Module::Install" # 5. The ./inc/ version of Module::Install loads # } ELSE { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install # 3. The ./inc/ version of Module::Install loads # } use 5.005; use strict 'vars'; use Cwd (); use File::Find (); use File::Path (); use FindBin; use vars qw{$VERSION $MAIN}; BEGIN { # All Module::Install core packages now require synchronised versions. # This will be used to ensure we don't accidentally load old or # different versions of modules. # This is not enforced yet, but will be some time in the next few # releases once we can make sure it won't clash with custom # Module::Install extensions. $VERSION = '0.95'; # Storage for the pseudo-singleton $MAIN = undef; *inc::Module::Install::VERSION = *VERSION; @inc::Module::Install::ISA = __PACKAGE__; } sub import { my $class = shift; my $self = $class->new(@_); my $who = $self->_caller; #------------------------------------------------------------- # all of the following checks should be included in import(), # to allow "eval 'require Module::Install; 1' to test # installation of Module::Install. (RT #51267) #------------------------------------------------------------- # Whether or not inc::Module::Install is actually loaded, the # $INC{inc/Module/Install.pm} is what will still get set as long as # the caller loaded module this in the documented manner. # If not set, the caller may NOT have loaded the bundled version, and thus # they may not have a MI version that works with the Makefile.PL. This would # result in false errors or unexpected behaviour. And we don't want that. my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; unless ( $INC{$file} ) { die <<"END_DIE" } Please invoke ${\__PACKAGE__} with: use inc::${\__PACKAGE__}; not: use ${\__PACKAGE__}; END_DIE # This reportedly fixes a rare Win32 UTC file time issue, but # as this is a non-cross-platform XS module not in the core, # we shouldn't really depend on it. See RT #24194 for detail. # (Also, this module only supports Perl 5.6 and above). eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; # If the script that is loading Module::Install is from the future, # then make will detect this and cause it to re-run over and over # again. This is bad. Rather than taking action to touch it (which # is unreliable on some platforms and requires write permissions) # for now we should catch this and refuse to run. if ( -f $0 ) { my $s = (stat($0))[9]; # If the modification time is only slightly in the future, # sleep briefly to remove the problem. my $a = $s - time; if ( $a > 0 and $a < 5 ) { sleep 5 } # Too far in the future, throw an error. my $t = time; if ( $s > $t ) { die <<"END_DIE" } Your installer $0 has a modification time in the future ($s > $t). This is known to create infinite loops in make. Please correct this, then run $0 again. END_DIE } # Build.PL was formerly supported, but no longer is due to excessive # difficulty in implementing every single feature twice. if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } Module::Install no longer supports Build.PL. It was impossible to maintain duel backends, and has been deprecated. Please remove all Build.PL files and only use the Makefile.PL installer. END_DIE #------------------------------------------------------------- # To save some more typing in Module::Install installers, every... # use inc::Module::Install # ...also acts as an implicit use strict. $^H |= strict::bits(qw(refs subs vars)); #------------------------------------------------------------- unless ( -f $self->{file} ) { require "$self->{path}/$self->{dispatch}.pm"; File::Path::mkpath("$self->{prefix}/$self->{author}"); $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); $self->{admin}->init; @_ = ($class, _self => $self); goto &{"$self->{name}::import"}; } *{"${who}::AUTOLOAD"} = $self->autoload; $self->preload; # Unregister loader and worker packages so subdirs can use them again delete $INC{"$self->{file}"}; delete $INC{"$self->{path}.pm"}; # Save to the singleton $MAIN = $self; return 1; } sub autoload { my $self = shift; my $who = $self->_caller; my $cwd = Cwd::cwd(); my $sym = "${who}::AUTOLOAD"; $sym->{$cwd} = sub { my $pwd = Cwd::cwd(); if ( my $code = $sym->{$pwd} ) { # Delegate back to parent dirs goto &$code unless $cwd eq $pwd; } $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym"; my $method = $1; if ( uc($method) eq $method ) { # Do nothing return; } elsif ( $method =~ /^_/ and $self->can($method) ) { # Dispatch to the root M:I class return $self->$method(@_); } # Dispatch to the appropriate plugin unshift @_, ( $self, $1 ); goto &{$self->can('call')}; }; } sub preload { my $self = shift; unless ( $self->{extensions} ) { $self->load_extensions( "$self->{prefix}/$self->{path}", $self ); } my @exts = @{$self->{extensions}}; unless ( @exts ) { @exts = $self->{admin}->load_all_extensions; } my %seen; foreach my $obj ( @exts ) { while (my ($method, $glob) = each %{ref($obj) . '::'}) { next unless $obj->can($method); next if $method =~ /^_/; next if $method eq uc($method); $seen{$method}++; } } my $who = $self->_caller; foreach my $name ( sort keys %seen ) { *{"${who}::$name"} = sub { ${"${who}::AUTOLOAD"} = "${who}::$name"; goto &{"${who}::AUTOLOAD"}; }; } } sub new { my ($class, %args) = @_; # ignore the prefix on extension modules built from top level. my $base_path = Cwd::abs_path($FindBin::Bin); unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { delete $args{prefix}; } return $args{_self} if $args{_self}; $args{dispatch} ||= 'Admin'; $args{prefix} ||= 'inc'; $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); $args{bundle} ||= 'inc/BUNDLES'; $args{base} ||= $base_path; $class =~ s/^\Q$args{prefix}\E:://; $args{name} ||= $class; $args{version} ||= $class->VERSION; unless ( $args{path} ) { $args{path} = $args{name}; $args{path} =~ s!::!/!g; } $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; $args{wrote} = 0; bless( \%args, $class ); } sub call { my ($self, $method) = @_; my $obj = $self->load($method) or return; splice(@_, 0, 2, $obj); goto &{$obj->can($method)}; } sub load { my ($self, $method) = @_; $self->load_extensions( "$self->{prefix}/$self->{path}", $self ) unless $self->{extensions}; foreach my $obj (@{$self->{extensions}}) { return $obj if $obj->can($method); } my $admin = $self->{admin} or die <<"END_DIE"; The '$method' method does not exist in the '$self->{prefix}' path! Please remove the '$self->{prefix}' directory and run $0 again to load it. END_DIE my $obj = $admin->load($method, 1); push @{$self->{extensions}}, $obj; $obj; } sub load_extensions { my ($self, $path, $top) = @_; unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { unshift @INC, $self->{prefix}; } foreach my $rv ( $self->find_extensions($path) ) { my ($file, $pkg) = @{$rv}; next if $self->{pathnames}{$pkg}; local $@; my $new = eval { require $file; $pkg->can('new') }; unless ( $new ) { warn $@ if $@; next; } $self->{pathnames}{$pkg} = delete $INC{$file}; push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); } $self->{extensions} ||= []; } sub find_extensions { my ($self, $path) = @_; my @found; File::Find::find( sub { my $file = $File::Find::name; return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; my $subpath = $1; return if lc($subpath) eq lc($self->{dispatch}); $file = "$self->{path}/$subpath.pm"; my $pkg = "$self->{name}::$subpath"; $pkg =~ s!/!::!g; # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { my $content = Module::Install::_read($subpath . '.pm'); my $in_pod = 0; foreach ( split //, $content ) { $in_pod = 1 if /^=\w/; $in_pod = 0 if /^=cut/; next if ($in_pod || /^=cut/); # skip pod text next if /^\s*#/; # and comments if ( m/^\s*package\s+($pkg)\s*;/i ) { $pkg = $1; last; } } } push @found, [ $file, $pkg ]; }, $path ) if -d $path; @found; } ##################################################################### # Common Utility Functions sub _caller { my $depth = 0; my $call = caller($depth); while ( $call eq __PACKAGE__ ) { $depth++; $call = caller($depth); } return $call; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _read { local *FH; open( FH, '<', $_[0] ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_NEW sub _read { local *FH; open( FH, "< $_[0]" ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_OLD sub _readperl { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; return $string; } sub _readpod { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; return $string if $_[0] =~ /\.pod\z/; $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; $string =~ s/^\n+//s; return $string; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _write { local *FH; open( FH, '>', $_[0] ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_NEW sub _write { local *FH; open( FH, "> $_[0]" ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_OLD # _version is for processing module versions (eg, 1.03_05) not # Perl versions (eg, 5.8.1). sub _version ($) { my $s = shift || 0; my $d =()= $s =~ /(\.)/g; if ( $d >= 2 ) { # Normalise multipart versions $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; } $s =~ s/^(\d+)\.?//; my $l = $1 || 0; my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g; $l = $l . '.' . join '', @v if @v; return $l + 0; } sub _cmp ($$) { _version($_[0]) <=> _version($_[1]); } # Cloned from Params::Util::_CLASS sub _CLASS ($) { ( defined $_[0] and ! ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s ) ? $_[0] : undef; } 1; # Copyright 2008 - 2010 Adam Kennedy. Locale-Hebrew-1.05/inc/Module/Install/Base.pm000644 000765 000024 00000001766 11377352510 020452 0ustar00austaff000000 000000 #line 1 package Module::Install::Base; use strict 'vars'; use vars qw{$VERSION}; BEGIN { $VERSION = '0.95'; } # Suspend handler for "redefined" warnings BEGIN { my $w = $SIG{__WARN__}; $SIG{__WARN__} = sub { $w }; } #line 42 sub new { my $class = shift; unless ( defined &{"${class}::call"} ) { *{"${class}::call"} = sub { shift->_top->call(@_) }; } unless ( defined &{"${class}::load"} ) { *{"${class}::load"} = sub { shift->_top->load(@_) }; } bless { @_ }, $class; } #line 61 sub AUTOLOAD { local $@; my $func = eval { shift->_top->autoload } or return; goto &$func; } #line 75 sub _top { $_[0]->{_top}; } #line 90 sub admin { $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new; } #line 106 sub is_admin { $_[0]->admin->VERSION; } sub DESTROY {} package Module::Install::Base::FakeAdmin; my $fake; sub new { $fake ||= bless(\@_, $_[0]); } sub AUTOLOAD {} sub DESTROY {} # Restore warning handler BEGIN { $SIG{__WARN__} = $SIG{__WARN__}->(); } 1; #line 154 Locale-Hebrew-1.05/inc/Module/Install/Can.pm000644 000765 000024 00000003333 11377352510 020271 0ustar00austaff000000 000000 #line 1 package Module::Install::Can; use strict; use Config (); use File::Spec (); use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # check if we can load some module ### Upgrade this to not have to load the module if possible sub can_use { my ($self, $mod, $ver) = @_; $mod =~ s{::|\\}{/}g; $mod .= '.pm' unless $mod =~ /\.pm$/i; my $pkg = $mod; $pkg =~ s{/}{::}g; $pkg =~ s{\.pm$}{}i; local $@; eval { require $mod; $pkg->VERSION($ver || 0); 1 }; } # check if we can run some command sub can_run { my ($self, $cmd) = @_; my $_cmd = $cmd; return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { next if $dir eq ''; my $abs = File::Spec->catfile($dir, $_[1]); return $abs if (-x $abs or $abs = MM->maybe_command($abs)); } return; } # can we locate a (the) C compiler sub can_cc { my $self = shift; my @chunks = split(/ /, $Config::Config{cc}) or return; # $Config{cc} may contain args; try to find out the program part while (@chunks) { return $self->can_run("@chunks") || (pop(@chunks), next); } return; } # Fix Cygwin bug on maybe_command(); if ( $^O eq 'cygwin' ) { require ExtUtils::MM_Cygwin; require ExtUtils::MM_Win32; if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { *ExtUtils::MM_Cygwin::maybe_command = sub { my ($self, $file) = @_; if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { ExtUtils::MM_Win32->maybe_command($file); } else { ExtUtils::MM_Unix->maybe_command($file); } } } } 1; __END__ #line 156 Locale-Hebrew-1.05/inc/Module/Install/Fetch.pm000644 000765 000024 00000004627 11377352510 020630 0ustar00austaff000000 000000 #line 1 package Module::Install::Fetch; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub get_file { my ($self, %args) = @_; my ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { $args{url} = $args{ftp_url} or (warn("LWP support unavailable!\n"), return); ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; } $|++; print "Fetching '$file' from $host... "; unless (eval { require Socket; Socket::inet_aton($host) }) { warn "'$host' resolve failed!\n"; return; } return unless $scheme eq 'ftp' or $scheme eq 'http'; require Cwd; my $dir = Cwd::getcwd(); chdir $args{local_dir} or return if exists $args{local_dir}; if (eval { require LWP::Simple; 1 }) { LWP::Simple::mirror($args{url}, $file); } elsif (eval { require Net::FTP; 1 }) { eval { # use Net::FTP to get past firewall my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); $ftp->login("anonymous", 'anonymous@example.com'); $ftp->cwd($path); $ftp->binary; $ftp->get($file) or (warn("$!\n"), return); $ftp->quit; } } elsif (my $ftp = $self->can_run('ftp')) { eval { # no Net::FTP, fallback to ftp.exe require FileHandle; my $fh = FileHandle->new; local $SIG{CHLD} = 'IGNORE'; unless ($fh->open("|$ftp -n")) { warn "Couldn't open ftp: $!\n"; chdir $dir; return; } my @dialog = split(/\n/, <<"END_FTP"); open $host user anonymous anonymous\@example.com cd $path binary get $file $file quit END_FTP foreach (@dialog) { $fh->print("$_\n") } $fh->close; } } else { warn "No working 'ftp' program available!\n"; chdir $dir; return; } unless (-f $file) { warn "Fetching failed: $@\n"; chdir $dir; return; } return if exists $args{size} and -s $file != $args{size}; system($args{run}) if exists $args{run}; unlink($file) if $args{remove}; print(((!exists $args{check_for} or -e $args{check_for}) ? "done!" : "failed! ($!)"), "\n"); chdir $dir; return !$?; } 1; Locale-Hebrew-1.05/inc/Module/Install/Makefile.pm000644 000765 000024 00000026220 11377352510 021305 0ustar00austaff000000 000000 #line 1 package Module::Install::Makefile; use strict 'vars'; use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub Makefile { $_[0] } my %seen = (); sub prompt { shift; # Infinite loop protection my @c = caller(); if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; } # In automated testing or non-interactive session, always use defaults if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { local $ENV{PERL_MM_USE_DEFAULT} = 1; goto &ExtUtils::MakeMaker::prompt; } else { goto &ExtUtils::MakeMaker::prompt; } } # Store a cleaned up version of the MakeMaker version, # since we need to behave differently in a variety of # ways based on the MM version. my $makemaker = eval $ExtUtils::MakeMaker::VERSION; # If we are passed a param, do a "newer than" comparison. # Otherwise, just return the MakeMaker version. sub makemaker { ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 } # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified # as we only need to know here whether the attribute is an array # or a hash or something else (which may or may not be appendable). my %makemaker_argtype = ( C => 'ARRAY', CONFIG => 'ARRAY', # CONFIGURE => 'CODE', # ignore DIR => 'ARRAY', DL_FUNCS => 'HASH', DL_VARS => 'ARRAY', EXCLUDE_EXT => 'ARRAY', EXE_FILES => 'ARRAY', FUNCLIST => 'ARRAY', H => 'ARRAY', IMPORTS => 'HASH', INCLUDE_EXT => 'ARRAY', LIBS => 'ARRAY', # ignore '' MAN1PODS => 'HASH', MAN3PODS => 'HASH', META_ADD => 'HASH', META_MERGE => 'HASH', PL_FILES => 'HASH', PM => 'HASH', PMLIBDIRS => 'ARRAY', PMLIBPARENTDIRS => 'ARRAY', PREREQ_PM => 'HASH', CONFIGURE_REQUIRES => 'HASH', SKIP => 'ARRAY', TYPEMAPS => 'ARRAY', XS => 'HASH', # VERSION => ['version',''], # ignore # _KEEP_AFTER_FLUSH => '', clean => 'HASH', depend => 'HASH', dist => 'HASH', dynamic_lib=> 'HASH', linkext => 'HASH', macro => 'HASH', postamble => 'HASH', realclean => 'HASH', test => 'HASH', tool_autosplit => 'HASH', # special cases where you can use makemaker_append CCFLAGS => 'APPENDABLE', DEFINE => 'APPENDABLE', INC => 'APPENDABLE', LDDLFLAGS => 'APPENDABLE', LDFROM => 'APPENDABLE', ); sub makemaker_args { my ($self, %new_args) = @_; my $args = ( $self->{makemaker_args} ||= {} ); foreach my $key (keys %new_args) { if ($makemaker_argtype{$key} eq 'ARRAY') { $args->{$key} = [] unless defined $args->{$key}; unless (ref $args->{$key} eq 'ARRAY') { $args->{$key} = [$args->{$key}] } push @{$args->{$key}}, ref $new_args{$key} eq 'ARRAY' ? @{$new_args{$key}} : $new_args{$key}; } elsif ($makemaker_argtype{$key} eq 'HASH') { $args->{$key} = {} unless defined $args->{$key}; foreach my $skey (keys %{ $new_args{$key} }) { $args->{$key}{$skey} = $new_args{$key}{$skey}; } } elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { $self->makemaker_append($key => $new_args{$key}); } else { if (defined $args->{$key}) { warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; } $args->{$key} = $new_args{$key}; } } return $args; } # For mm args that take multiple space-seperated args, # append an argument to the current list. sub makemaker_append { my $self = shift; my $name = shift; my $args = $self->makemaker_args; $args->{$name} = defined $args->{$name} ? join( ' ', $args->{$name}, @_ ) : join( ' ', @_ ); } sub build_subdirs { my $self = shift; my $subdirs = $self->makemaker_args->{DIR} ||= []; for my $subdir (@_) { push @$subdirs, $subdir; } } sub clean_files { my $self = shift; my $clean = $self->makemaker_args->{clean} ||= {}; %$clean = ( %$clean, FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), ); } sub realclean_files { my $self = shift; my $realclean = $self->makemaker_args->{realclean} ||= {}; %$realclean = ( %$realclean, FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), ); } sub libs { my $self = shift; my $libs = ref $_[0] ? shift : [ shift ]; $self->makemaker_args( LIBS => $libs ); } sub inc { my $self = shift; $self->makemaker_args( INC => shift ); } my %test_dir = (); sub _wanted_t { /\.t$/ and -f $_ and $test_dir{$File::Find::dir} = 1; } sub tests_recursive { my $self = shift; if ( $self->tests ) { die "tests_recursive will not work if tests are already defined"; } my $dir = shift || 't'; unless ( -d $dir ) { die "tests_recursive dir '$dir' does not exist"; } %test_dir = (); require File::Find; File::Find::find( \&_wanted_t, $dir ); if ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { File::Find::find( \&_wanted_t, 'xt' ); } $self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir ); } sub write { my $self = shift; die "&Makefile->write() takes no arguments\n" if @_; # Check the current Perl version my $perl_version = $self->perl_version; if ( $perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; } # Make sure we have a new enough MakeMaker require ExtUtils::MakeMaker; if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { # MakeMaker can complain about module versions that include # an underscore, even though its own version may contain one! # Hence the funny regexp to get rid of it. See RT #35800 # for details. my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/; $self->build_requires( 'ExtUtils::MakeMaker' => $v ); $self->configure_requires( 'ExtUtils::MakeMaker' => $v ); } else { # Allow legacy-compatibility with 5.005 by depending on the # most recent EU:MM that supported 5.005. $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 ); } # Generate the MakeMaker params my $args = $self->makemaker_args; $args->{DISTNAME} = $self->name; $args->{NAME} = $self->module_name || $self->name; $args->{NAME} =~ s/-/::/g; $args->{VERSION} = $self->version or die <<'EOT'; ERROR: Can't determine distribution version. Please specify it explicitly via 'version' in Makefile.PL, or set a valid $VERSION in a module, and provide its file path via 'version_from' (or 'all_from' if you prefer) in Makefile.PL. EOT $DB::single = 1; if ( $self->tests ) { my @tests = split ' ', $self->tests; my %seen; $args->{test} = { TESTS => (join ' ', grep {!$seen{$_}++} @tests), }; } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { $args->{test} = { TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), }; } if ( $] >= 5.005 ) { $args->{ABSTRACT} = $self->abstract; $args->{AUTHOR} = join ', ', @{$self->author || []}; } if ( $self->makemaker(6.10) ) { $args->{NO_META} = 1; #$args->{NO_MYMETA} = 1; } if ( $self->makemaker(6.17) and $self->sign ) { $args->{SIGN} = 1; } unless ( $self->is_admin ) { delete $args->{SIGN}; } if ( $self->makemaker(6.31) and $self->license ) { $args->{LICENSE} = $self->license; } my $prereq = ($args->{PREREQ_PM} ||= {}); %$prereq = ( %$prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->requires) ); # Remove any reference to perl, PREREQ_PM doesn't support it delete $args->{PREREQ_PM}->{perl}; # Merge both kinds of requires into BUILD_REQUIRES my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); %$build_prereq = ( %$build_prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->configure_requires, $self->build_requires) ); # Remove any reference to perl, BUILD_REQUIRES doesn't support it delete $args->{BUILD_REQUIRES}->{perl}; # Delete bundled dists from prereq_pm my $subdirs = ($args->{DIR} ||= []); if ($self->bundles) { foreach my $bundle (@{ $self->bundles }) { my ($file, $dir) = @$bundle; push @$subdirs, $dir if -d $dir; delete $build_prereq->{$file}; #Delete from build prereqs only } } unless ( $self->makemaker('6.55_03') ) { %$prereq = (%$prereq,%$build_prereq); delete $args->{BUILD_REQUIRES}; } if ( my $perl_version = $self->perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; if ( $self->makemaker(6.48) ) { $args->{MIN_PERL_VERSION} = $perl_version; } } if ($self->installdirs) { warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; $args->{INSTALLDIRS} = $self->installdirs; } my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) } keys %$args; my $user_preop = delete $args{dist}->{PREOP}; if ( my $preop = $self->admin->preop($user_preop) ) { foreach my $key ( keys %$preop ) { $args{dist}->{$key} = $preop->{$key}; } } my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); } sub fix_up_makefile { my $self = shift; my $makefile_name = shift; my $top_class = ref($self->_top) || ''; my $top_version = $self->_top->VERSION || ''; my $preamble = $self->preamble ? "# Preamble by $top_class $top_version\n" . $self->preamble : ''; my $postamble = "# Postamble by $top_class $top_version\n" . ($self->postamble || ''); local *MAKEFILE; open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; my $makefile = do { local $/; }; close MAKEFILE or die $!; $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; # Module::Install will never be used to build the Core Perl # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; # XXX - This is currently unused; not sure if it breaks other MM-users # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; open MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; print MAKEFILE "$preamble$makefile$postamble" or die $!; close MAKEFILE or die $!; 1; } sub preamble { my ($self, $text) = @_; $self->{preamble} = $text . $self->{preamble} if defined $text; $self->{preamble}; } sub postamble { my ($self, $text) = @_; $self->{postamble} ||= $self->admin->postamble; $self->{postamble} .= $text if defined $text; $self->{postamble} } 1; __END__ #line 531 Locale-Hebrew-1.05/inc/Module/Install/Metadata.pm000644 000765 000024 00000041000 11377352510 021301 0ustar00austaff000000 000000 #line 1 package Module::Install::Metadata; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } my @boolean_keys = qw{ sign }; my @scalar_keys = qw{ name module_name abstract version distribution_type tests installdirs }; my @tuple_keys = qw{ configure_requires build_requires requires recommends bundles resources }; my @resource_keys = qw{ homepage bugtracker repository }; my @array_keys = qw{ keywords author }; *authors = \&author; sub Meta { shift } sub Meta_BooleanKeys { @boolean_keys } sub Meta_ScalarKeys { @scalar_keys } sub Meta_TupleKeys { @tuple_keys } sub Meta_ResourceKeys { @resource_keys } sub Meta_ArrayKeys { @array_keys } foreach my $key ( @boolean_keys ) { *$key = sub { my $self = shift; if ( defined wantarray and not @_ ) { return $self->{values}->{$key}; } $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); return $self; }; } foreach my $key ( @scalar_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} = shift; return $self; }; } foreach my $key ( @array_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} ||= []; push @{$self->{values}->{$key}}, @_; return $self; }; } foreach my $key ( @resource_keys ) { *$key = sub { my $self = shift; unless ( @_ ) { return () unless $self->{values}->{resources}; return map { $_->[1] } grep { $_->[0] eq $key } @{ $self->{values}->{resources} }; } return $self->{values}->{resources}->{$key} unless @_; my $uri = shift or die( "Did not provide a value to $key()" ); $self->resources( $key => $uri ); return 1; }; } foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { *$key = sub { my $self = shift; return $self->{values}->{$key} unless @_; my @added; while ( @_ ) { my $module = shift or last; my $version = shift || 0; push @added, [ $module, $version ]; } push @{ $self->{values}->{$key} }, @added; return map {@$_} @added; }; } # Resource handling my %lc_resource = map { $_ => 1 } qw{ homepage license bugtracker repository }; sub resources { my $self = shift; while ( @_ ) { my $name = shift or last; my $value = shift or next; if ( $name eq lc $name and ! $lc_resource{$name} ) { die("Unsupported reserved lowercase resource '$name'"); } $self->{values}->{resources} ||= []; push @{ $self->{values}->{resources} }, [ $name, $value ]; } $self->{values}->{resources}; } # Aliases for build_requires that will have alternative # meanings in some future version of META.yml. sub test_requires { shift->build_requires(@_) } sub install_requires { shift->build_requires(@_) } # Aliases for installdirs options sub install_as_core { $_[0]->installdirs('perl') } sub install_as_cpan { $_[0]->installdirs('site') } sub install_as_site { $_[0]->installdirs('site') } sub install_as_vendor { $_[0]->installdirs('vendor') } sub dynamic_config { my $self = shift; unless ( @_ ) { warn "You MUST provide an explicit true/false value to dynamic_config\n"; return $self; } $self->{values}->{dynamic_config} = $_[0] ? 1 : 0; return 1; } sub perl_version { my $self = shift; return $self->{values}->{perl_version} unless @_; my $version = shift or die( "Did not provide a value to perl_version()" ); # Normalize the version $version = $self->_perl_version($version); # We don't support the reall old versions unless ( $version >= 5.005 ) { die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; } $self->{values}->{perl_version} = $version; } #Stolen from M::B my %license_urls = ( perl => 'http://dev.perl.org/licenses/', apache => 'http://apache.org/licenses/LICENSE-2.0', artistic => 'http://opensource.org/licenses/artistic-license.php', artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', lgpl => 'http://opensource.org/licenses/lgpl-license.php', lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', bsd => 'http://opensource.org/licenses/bsd-license.php', gpl => 'http://opensource.org/licenses/gpl-license.php', gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', mit => 'http://opensource.org/licenses/mit-license.php', mozilla => 'http://opensource.org/licenses/mozilla1.1.php', open_source => undef, unrestricted => undef, restrictive => undef, unknown => undef, ); sub license { my $self = shift; return $self->{values}->{license} unless @_; my $license = shift or die( 'Did not provide a value to license()' ); $self->{values}->{license} = $license; # Automatically fill in license URLs if ( $license_urls{$license} ) { $self->resources( license => $license_urls{$license} ); } return 1; } sub all_from { my ( $self, $file ) = @_; unless ( defined($file) ) { my $name = $self->name or die( "all_from called with no args without setting name() first" ); $file = join('/', 'lib', split(/-/, $name)) . '.pm'; $file =~ s{.*/}{} unless -e $file; unless ( -e $file ) { die("all_from cannot find $file from $name"); } } unless ( -f $file ) { die("The path '$file' does not exist, or is not a file"); } $self->{values}{all_from} = $file; # Some methods pull from POD instead of code. # If there is a matching .pod, use that instead my $pod = $file; $pod =~ s/\.pm$/.pod/i; $pod = $file unless -e $pod; # Pull the different values $self->name_from($file) unless $self->name; $self->version_from($file) unless $self->version; $self->perl_version_from($file) unless $self->perl_version; $self->author_from($pod) unless @{$self->author || []}; $self->license_from($pod) unless $self->license; $self->abstract_from($pod) unless $self->abstract; return 1; } sub provides { my $self = shift; my $provides = ( $self->{values}->{provides} ||= {} ); %$provides = (%$provides, @_) if @_; return $provides; } sub auto_provides { my $self = shift; return $self unless $self->is_admin; unless (-e 'MANIFEST') { warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; return $self; } # Avoid spurious warnings as we are not checking manifest here. local $SIG{__WARN__} = sub {1}; require ExtUtils::Manifest; local *ExtUtils::Manifest::manicheck = sub { return }; require Module::Build; my $build = Module::Build->new( dist_name => $self->name, dist_version => $self->version, license => $self->license, ); $self->provides( %{ $build->find_dist_packages || {} } ); } sub feature { my $self = shift; my $name = shift; my $features = ( $self->{values}->{features} ||= [] ); my $mods; if ( @_ == 1 and ref( $_[0] ) ) { # The user used ->feature like ->features by passing in the second # argument as a reference. Accomodate for that. $mods = $_[0]; } else { $mods = \@_; } my $count = 0; push @$features, ( $name => [ map { ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ } @$mods ] ); return @$features; } sub features { my $self = shift; while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { $self->feature( $name, @$mods ); } return $self->{values}->{features} ? @{ $self->{values}->{features} } : (); } sub no_index { my $self = shift; my $type = shift; push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; return $self->{values}->{no_index}; } sub read { my $self = shift; $self->include_deps( 'YAML::Tiny', 0 ); require YAML::Tiny; my $data = YAML::Tiny::LoadFile('META.yml'); # Call methods explicitly in case user has already set some values. while ( my ( $key, $value ) = each %$data ) { next unless $self->can($key); if ( ref $value eq 'HASH' ) { while ( my ( $module, $version ) = each %$value ) { $self->can($key)->($self, $module => $version ); } } else { $self->can($key)->($self, $value); } } return $self; } sub write { my $self = shift; return $self unless $self->is_admin; $self->admin->write_meta; return $self; } sub version_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->version( ExtUtils::MM_Unix->parse_version($file) ); } sub abstract_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->abstract( bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix' )->parse_abstract($file) ); } # Add both distribution and module name sub name_from { my ($self, $file) = @_; if ( Module::Install::_read($file) =~ m/ ^ \s* package \s* ([\w:]+) \s* ; /ixms ) { my ($name, $module_name) = ($1, $1); $name =~ s{::}{-}g; $self->name($name); unless ( $self->module_name ) { $self->module_name($module_name); } } else { die("Cannot determine name from $file\n"); } } sub _extract_perl_version { if ( $_[0] =~ m/ ^\s* (?:use|require) \s* v? ([\d_\.]+) \s* ; /ixms ) { my $perl_version = $1; $perl_version =~ s{_}{}g; return $perl_version; } else { return; } } sub perl_version_from { my $self = shift; my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); if ($perl_version) { $self->perl_version($perl_version); } else { warn "Cannot determine perl version info from $_[0]\n"; return; } } sub author_from { my $self = shift; my $content = Module::Install::_read($_[0]); if ($content =~ m/ =head \d \s+ (?:authors?)\b \s* ([^\n]*) | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* ([^\n]*) /ixms) { my $author = $1 || $2; # XXX: ugly but should work anyway... if (eval "require Pod::Escapes; 1") { # Pod::Escapes has a mapping table. # It's in core of perl >= 5.9.3, and should be installed # as one of the Pod::Simple's prereqs, which is a prereq # of Pod::Text 3.x (see also below). $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $Pod::Escapes::Name2character_number{$1} ? chr($Pod::Escapes::Name2character_number{$1}) : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { # Pod::Text < 3.0 has yet another mapping table, # though the table name of 2.x and 1.x are different. # (1.x is in core of Perl < 5.6, 2.x is in core of # Perl < 5.9.3) my $mapping = ($Pod::Text::VERSION < 2) ? \%Pod::Text::HTML_Escapes : \%Pod::Text::ESCAPES; $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $mapping->{$1} ? $mapping->{$1} : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } else { $author =~ s{E}{<}g; $author =~ s{E}{>}g; } $self->author($author); } else { warn "Cannot determine author info from $_[0]\n"; } } sub _extract_license { my $pod = shift; my $matched; return __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:licen[cs]e|licensing)\b.*?) (=head \d.*|=cut.*|)\z /ixms ) || __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:copyrights?|legal)\b.*?) (=head \d.*|=cut.*|)\z /ixms ); } sub __extract_license { my $license_text = shift or return; my @phrases = ( 'under the same (?:terms|license) as (?:perl|the perl programming language)' => 'perl', 1, 'under the terms of (?:perl|the perl programming language) itself' => 'perl', 1, 'Artistic and GPL' => 'perl', 1, 'GNU general public license' => 'gpl', 1, 'GNU public license' => 'gpl', 1, 'GNU lesser general public license' => 'lgpl', 1, 'GNU lesser public license' => 'lgpl', 1, 'GNU library general public license' => 'lgpl', 1, 'GNU library public license' => 'lgpl', 1, 'BSD license' => 'bsd', 1, 'Artistic license' => 'artistic', 1, 'GPL' => 'gpl', 1, 'LGPL' => 'lgpl', 1, 'BSD' => 'bsd', 1, 'Artistic' => 'artistic', 1, 'MIT' => 'mit', 1, 'proprietary' => 'proprietary', 0, ); while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { $pattern =~ s#\s+#\\s+#gs; if ( $license_text =~ /\b$pattern\b/i ) { return $license; } } } sub license_from { my $self = shift; if (my $license=_extract_license(Module::Install::_read($_[0]))) { $self->license($license); } else { warn "Cannot determine license info from $_[0]\n"; return 'unknown'; } } sub _extract_bugtracker { my @links = $_[0] =~ m#L<( \Qhttp://rt.cpan.org/\E[^>]+| \Qhttp://github.com/\E[\w_]+/[\w_]+/issues| \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list )>#gx; my %links; @links{@links}=(); @links=keys %links; return @links; } sub bugtracker_from { my $self = shift; my $content = Module::Install::_read($_[0]); my @links = _extract_bugtracker($content); unless ( @links ) { warn "Cannot determine bugtracker info from $_[0]\n"; return 0; } if ( @links > 1 ) { warn "Found more than one bugtracker link in $_[0]\n"; return 0; } # Set the bugtracker bugtracker( $links[0] ); return 1; } sub requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->requires( $module => $version ); } } sub test_requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->test_requires( $module => $version ); } } # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to # numbers (eg, 5.006001 or 5.008009). # Also, convert double-part versions (eg, 5.8) sub _perl_version { my $v = $_[-1]; $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; $v =~ s/(\.\d\d\d)000$/$1/; $v =~ s/_.+$//; if ( ref($v) ) { # Numify $v = $v + 0; } return $v; } ###################################################################### # MYMETA Support sub WriteMyMeta { die "WriteMyMeta has been deprecated"; } sub write_mymeta_yaml { my $self = shift; # We need YAML::Tiny to write the MYMETA.yml file unless ( eval { require YAML::Tiny; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.yml\n"; YAML::Tiny::DumpFile('MYMETA.yml', $meta); } sub write_mymeta_json { my $self = shift; # We need JSON to write the MYMETA.json file unless ( eval { require JSON; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.json\n"; Module::Install::_write( 'MYMETA.json', JSON->new->pretty(1)->canonical->encode($meta), ); } sub _write_mymeta_data { my $self = shift; # If there's no existing META.yml there is nothing we can do return undef unless -f 'META.yml'; # We need Parse::CPAN::Meta to load the file unless ( eval { require Parse::CPAN::Meta; 1; } ) { return undef; } # Merge the perl version into the dependencies my $val = $self->Meta->{values}; my $perl = delete $val->{perl_version}; if ( $perl ) { $val->{requires} ||= []; my $requires = $val->{requires}; # Canonize to three-dot version after Perl 5.6 if ( $perl >= 5.006 ) { $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e } unshift @$requires, [ perl => $perl ]; } # Load the advisory META.yml file my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); my $meta = $yaml[0]; # Overwrite the non-configure dependency hashs delete $meta->{requires}; delete $meta->{build_requires}; delete $meta->{recommends}; if ( exists $val->{requires} ) { $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; } if ( exists $val->{build_requires} ) { $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; } return $meta; } 1; Locale-Hebrew-1.05/inc/Module/Install/Win32.pm000644 000765 000024 00000003403 11377352510 020470 0ustar00austaff000000 000000 #line 1 package Module::Install::Win32; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # determine if the user needs nmake, and download it if needed sub check_nmake { my $self = shift; $self->load('can_run'); $self->load('get_file'); require Config; return unless ( $^O eq 'MSWin32' and $Config::Config{make} and $Config::Config{make} =~ /^nmake\b/i and ! $self->can_run('nmake') ); print "The required 'nmake' executable not found, fetching it...\n"; require File::Basename; my $rv = $self->get_file( url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', local_dir => File::Basename::dirname($^X), size => 51928, run => 'Nmake15.exe /o > nul', check_for => 'Nmake.exe', remove => 1, ); die <<'END_MESSAGE' unless $rv; ------------------------------------------------------------------------------- Since you are using Microsoft Windows, you will need the 'nmake' utility before installation. It's available at: http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe or ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe Please download the file manually, save it to a directory in %PATH% (e.g. C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to that directory, and run "Nmake15.exe" from there; that will create the 'nmake.exe' file needed by this module. You may then resume the installation process described in README. ------------------------------------------------------------------------------- END_MESSAGE } 1; Locale-Hebrew-1.05/inc/Module/Install/WriteAll.pm000644 000765 000024 00000002377 11377352510 021322 0ustar00austaff000000 000000 #line 1 package Module::Install::WriteAll; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '0.95';; @ISA = qw{Module::Install::Base}; $ISCORE = 1; } sub WriteAll { my $self = shift; my %args = ( meta => 1, sign => 0, inline => 0, check_nmake => 1, @_, ); $self->sign(1) if $args{sign}; $self->admin->WriteAll(%args) if $self->is_admin; $self->check_nmake if $args{check_nmake}; unless ( $self->makemaker_args->{PL_FILES} ) { # XXX: This still may be a bit over-defensive... unless ($self->makemaker(6.25)) { $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; } } # Until ExtUtils::MakeMaker support MYMETA.yml, make sure # we clean it up properly ourself. $self->realclean_files('MYMETA.yml'); if ( $args{inline} ) { $self->Inline->write; } else { $self->Makefile->write; } # The Makefile write process adds a couple of dependencies, # so write the META.yml files after the Makefile. if ( $args{meta} ) { $self->Meta->write; } # Experimental support for MYMETA if ( $ENV{X_MYMETA} ) { if ( $ENV{X_MYMETA} eq 'JSON' ) { $self->Meta->write_mymeta_json; } else { $self->Meta->write_mymeta_yaml; } } return 1; } 1;