/* * Set up for a new numeric locale. */ void Perl_new_numeric(pTHX_ const char *newnum) { #ifdef USE_LOCALE_NUMERIC dVAR; if (! newnum) { Safefree(PL_numeric_name); PL_numeric_name = NULL; PL_numeric_standard = TRUE; PL_numeric_local = TRUE; return; } if (! PL_numeric_name || strNE(PL_numeric_name, newnum)) { Safefree(PL_numeric_name); PL_numeric_name = stdize_locale(savepv(newnum)); PL_numeric_standard = ((*newnum == 'C' && newnum[1] == '\0') || strEQ(newnum, "POSIX")); PL_numeric_local = TRUE; set_numeric_radix(); } #endif /* USE_LOCALE_NUMERIC */ }
STR * hfetch(HASH *tb, char *key) { char *s; int i; int hash; HENT *entry; if (!tb) return NULL; for (s=key, i=0, hash = 0; /* while */ *s; s++, i++, hash *= 5) { hash += *s * coeff[i]; } entry = tb->tbl_array[hash & tb->tbl_max]; for (; entry; entry = entry->hent_next) { if (entry->hent_hash != hash) /* strings can't be equal */ continue; if (strNE(entry->hent_key,key)) /* is this it? */ continue; return entry->hent_val; } return NULL; }
bool hstore(HASH *tb, char *key, STR *val) { char *s; int i; int hash; HENT *entry; HENT **oentry; if (!tb) return FALSE; for (s=key, i=0, hash = 0; /* while */ *s; s++, i++, hash *= 5) { hash += *s * coeff[i]; } oentry = &(tb->tbl_array[hash & tb->tbl_max]); i = 1; for (entry = *oentry; entry; i=0, entry = entry->hent_next) { if (entry->hent_hash != hash) /* strings can't be equal */ continue; if (strNE(entry->hent_key,key)) /* is this it? */ continue; /*NOSTRICT*/ safefree(entry->hent_val); entry->hent_val = val; return TRUE; } /*NOSTRICT*/ entry = (HENT*) safemalloc(sizeof(HENT)); entry->hent_key = savestr(key); entry->hent_val = val; entry->hent_hash = hash; entry->hent_next = *oentry; *oentry = entry; if (i) { /* initial entry? */ tb->tbl_fill++; if ((tb->tbl_fill * 100 / (tb->tbl_max + 1)) > FILLPCT) hsplit(tb); } return FALSE; }
/* * Set up for a new collation locale. */ void Perl_new_collate(pTHX_ const char *newcoll) { #ifdef USE_LOCALE_COLLATE dVAR; if (! newcoll) { if (PL_collation_name) { ++PL_collation_ix; Safefree(PL_collation_name); PL_collation_name = NULL; } PL_collation_standard = TRUE; PL_collxfrm_base = 0; PL_collxfrm_mult = 2; return; } if (! PL_collation_name || strNE(PL_collation_name, newcoll)) { ++PL_collation_ix; Safefree(PL_collation_name); PL_collation_name = stdize_locale(savepv(newcoll)); PL_collation_standard = ((*newcoll == 'C' && newcoll[1] == '\0') || strEQ(newcoll, "POSIX")); { /* 2: at most so many chars ('a', 'b'). */ /* 50: surely no system expands a char more. */ #define XFRMBUFSIZE (2 * 50) char xbuf[XFRMBUFSIZE]; const Size_t fa = strxfrm(xbuf, "a", XFRMBUFSIZE); const Size_t fb = strxfrm(xbuf, "ab", XFRMBUFSIZE); const SSize_t mult = fb - fa; if (mult < 1 && !(fa == 0 && fb == 0)) Perl_croak(aTHX_ "panic: strxfrm() gets absurd - a => %"UVuf", ab => %"UVuf, (UV) fa, (UV) fb); PL_collxfrm_base = (fa > (Size_t)mult) ? (fa - mult) : 0; PL_collxfrm_mult = mult; } } #endif /* USE_LOCALE_COLLATE */ }
static char* parse_buf(pTHX_ PSTATE* p_state, char *beg, char *end, U32 utf8, SV* self) { char *s = beg; char *t = beg; char *new_pos; while (!p_state->eof) { /* * At the start of this loop we will always be ready for eating text * or a new tag. We will never be inside some tag. The 't' points * to where we started and the 's' is advanced as we go. */ while (p_state->literal_mode) { char *l = p_state->literal_mode; bool skip_quoted_end = (strEQ(l, "script") || strEQ(l, "style")); char inside_quote = 0; bool escape_next = 0; char *end_text; while (s < end) { if (*s == '<' && !inside_quote) break; if (skip_quoted_end) { if (escape_next) { escape_next = 0; } else { if (*s == '\\') escape_next = 1; else if (inside_quote && *s == inside_quote) inside_quote = 0; else if (*s == '\r' || *s == '\n') inside_quote = 0; else if (!inside_quote && (*s == '"' || *s == '\'')) inside_quote = *s; } } s++; } if (s == end) { s = t; goto DONE; } end_text = s; s++; /* here we rely on '\0' termination of perl svpv buffers */ if (*s == '/') { s++; while (*l && toLOWER(*s) == *l) { s++; l++; } if (!*l && (strNE(p_state->literal_mode, "plaintext") || p_state->closing_plaintext)) { /* matched it all */ token_pos_t end_token; end_token.beg = end_text + 2; end_token.end = s; while (isHSPACE(*s)) s++; if (*s == '>') { s++; if (t != end_text) report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_END, end_text, s, utf8, &end_token, 1, self); p_state->literal_mode = 0; p_state->is_cdata = 0; t = s; } } } } #ifdef MARKED_SECTION while (p_state->ms == MS_CDATA || p_state->ms == MS_RCDATA) { while (s < end && *s != ']') s++; if (*s == ']') { char *end_text = s; s++; if (*s == ']') { s++; if (*s == '>') { s++; /* marked section end */ if (t != end_text) report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_NONE, end_text, s, utf8, 0, 0, self); t = s; SvREFCNT_dec(av_pop(p_state->ms_stack)); marked_section_update(p_state); continue; } } } if (s == end) { s = t; goto DONE; } } #endif /* first we try to match as much text as possible */ while (s < end && *s != '<') { #ifdef MARKED_SECTION if (p_state->ms && *s == ']') { char *end_text = s; s++; if (*s == ']') { s++; if (*s == '>') { s++; report_event(p_state, E_TEXT, t, end_text, utf8, 0, 0, self); report_event(p_state, E_NONE, end_text, s, utf8, 0, 0, self); t = s; SvREFCNT_dec(av_pop(p_state->ms_stack)); marked_section_update(p_state); continue; } } } #endif s++; } if (s != t) { if (*s == '<') { report_event(p_state, E_TEXT, t, s, utf8, 0, 0, self); t = s; } else { s--; if (isHSPACE(*s)) { /* wait with white space at end */ while (s >= t && isHSPACE(*s)) s--; } else { /* might be a chopped up entities/words */ while (s >= t && !isHSPACE(*s)) s--; while (s >= t && isHSPACE(*s)) s--; } s++; if (s != t) report_event(p_state, E_TEXT, t, s, utf8, 0, 0, self); break; } } if (end - s < 3) break; /* next char is known to be '<' and pointed to by 't' as well as 's' */ s++; #ifdef USE_PFUNC new_pos = parsefunc[(unsigned char)*s](p_state, t, end, utf8, self); #else if (isHNAME_FIRST(*s)) new_pos = parse_start(p_state, t, end, utf8, self); else if (*s == '/') new_pos = parse_end(p_state, t, end, utf8, self); else if (*s == '!') new_pos = parse_decl(p_state, t, end, utf8, self); else if (*s == '?') new_pos = parse_process(p_state, t, end, utf8, self); else new_pos = 0; #endif /* USE_PFUNC */ if (new_pos) { if (new_pos == t) { /* no progress, need more data to know what it is */ s = t; break; } t = s = new_pos; } /* if we get out here then this was not a conforming tag, so * treat it is plain text at the top of the loop again (we * have already skipped past the "<"). */ } DONE: return s; }
/* * Function to do a complete selection screen */ int iSelect_Browser(int wYSize, int wXSize, int wYPos, int wXPos, int selectpos, int multiselect, int sYSize, int sXSize, int sYPos, int sXPos, char *title, char *name, int mYSize, int mXSize, int mYPos, int mXPos, char **keystr, char *tagbegin, char *tagend) { WINDOW *wField; WINDOW *sField; WINDOW *mField; WINDOW *hField; int i; int nFirstLine, nLastLine; /* first & last line in buffer */ int nAbsFirstLine, nAbsLastLine; /* first & last line of output buffer */ int nRelMarked; /* relative line inside output buffer of marked line */ int nRelFirstDraw, nRelLastDraw; /* relative first & last line inside output buffer */ int c; int bEOI; int bQuit = FALSE; int y; int x; char msg[1024]; char ca[1024]; char ca3[1024]; char *cp; char *cp2; char *cp3; char **cpp; int ok; int bAllowEmpty; /* * Browser field */ wField = newwin(wYSize, wXSize, wYPos, wXPos); werase(wField); crmode(); noecho(); keypad(wField, TRUE); scrollok(wField, FALSE); /* * Status field */ sField = newwin(sYSize, sXSize, sYPos, sXPos); werase(sField); strcpy(msg, ""); /* * Message field */ mField = newwin(mYSize, mXSize, mYPos, mXPos); werase(mField); /* dimension of file */ nFirstLine = 0; nLastLine = nLines-1; /* determine curses select position */ if (selectpos < -1) selectpos = -1; if (selectpos > nLastLine) selectpos = nLastLine; if (selectpos == -1) { selectpos = 0; /* search for first selectable line */ for (i = nFirstLine; i < nLastLine; i++) { if (spaLines[i]->fSelectable) { selectpos = i; break; } } } /* calculate browser view borders */ if (nLastLine < (wYSize-1)) { /* buffer has fewer lines then our browser window */ nAbsFirstLine = nFirstLine; nAbsLastLine = nLastLine; nRelFirstDraw = 0; nRelLastDraw = nLastLine-nFirstLine; nRelMarked = selectpos; } else { /* browser window is smaller then file */ /* find top view position, so adjust the cursor into the middle of the browser window */ y = selectpos - (int)((wYSize-1)/2); if (y <= 0) y = 0; if (y+(wYSize-1) > nLastLine) y = nLastLine-(wYSize-1); nAbsFirstLine = y; nAbsLastLine = y+(wYSize-1); nRelFirstDraw = 0; nRelLastDraw = (wYSize-1); nRelMarked = selectpos-y; } ok = FALSE; for (i = nFirstLine; i < nLastLine; i++) { if (spaLines[i]->fSelectable) { ok = TRUE; break; } } if (!ok) strcpy(msg, "WARNING! No lines selectable."); bEOI = FALSE; while (bEOI == FALSE) { iSelect_Draw(wField, wYSize, wXSize, wYPos, wXPos, nAbsFirstLine, nAbsLastLine, nRelMarked, nRelFirstDraw, nRelLastDraw, nLines, sField, title, name, mField, msg, tagbegin, tagend); wrefresh(wField); strcpy(msg, ""); c = wgetch(wField); *keystr = key2asc(c); c = do_custom_key(c); if (c == KEY_LEFT) c = 'q'; if (c == KEY_RIGHT) c = '\n'; if (c >= KEY_MIN && c <= KEY_MAX) { /* * a curses special function key */ if (c == KEY_DOWN) { if (nAbsFirstLine+nRelMarked < nAbsLastLine) { nRelMarked++; /* nRelFirstDraw=nRelMarked-1; !!OPTIMIZE!! */ /* nRelLastDraw=nRelMarked; !!OPTIMIZE!! */ } else { if (nAbsLastLine < nLastLine) { wscrl(wField, 1); nAbsFirstLine++; nAbsLastLine++; /* nRelFirstDraw=(wYSize-1); !!OPTIMIZE!! */ /* nRelLastDraw=(wYSize-1); !!OPTIMIZE!!*/ } else { strcpy(msg, "Already at End."); } } } else if (c == KEY_UP) { if (nRelMarked > 0) { nRelMarked--; /* nRelLastDraw=nRelMarked; !!OPTIMIZE!! */ /* nRelFirstDraw=nRelMarked+1; !!OPTIMIZE!! */ } else { if (nAbsFirstLine > nFirstLine) { wscrl(wField, -1); nAbsFirstLine--; nAbsLastLine--; /* nRelFirstDraw=0 !!OPTIMIZE!! */ /* nRelLastDraw=0; !!OPTIMIZE!! */ } else { strcpy(msg, "Already at Begin."); } } } else if (c == KEY_NPAGE) { if (nAbsFirstLine+nRelMarked == nLastLine) { strcpy(msg, "Already at End."); } else { for (i = 0; i < (wYSize-1); i++) { if (nAbsFirstLine+nRelMarked < nAbsLastLine) nRelMarked++; else { if (nAbsLastLine < nLastLine) { wscrl(wField, 1); nAbsFirstLine++; nAbsLastLine++; } } } } } else if (c == KEY_PPAGE) { if (nAbsFirstLine+nRelMarked == nFirstLine) { strcpy(msg, "Already at Begin."); } else { for (i = 0; i < (wYSize-1); i++) { if (nRelMarked > 0) nRelMarked--; else { if (nAbsFirstLine > nFirstLine) { wscrl(wField, -1); nAbsFirstLine--; nAbsLastLine--; } } } } } else { strcpy(msg, "Invalid special key. Press 'h' for Help Page!"); } } else { c = c & 0xff; /* strip down to 8bit */ if (c < 32 || c > 126) { /* * a control code */ if (c == '\n' || c == '\r') { /* RETURN */ if (spaLines[nAbsFirstLine+nRelMarked]->fSelectable) { spaLines[nAbsFirstLine+nRelMarked]->fSelected = TRUE; bEOI = TRUE; } else { if (multiselect) { for (i = 0; i < nLines; i++) { if (spaLines[i]->fSelected) { bEOI = TRUE; break; } } if (!bEOI) strcpy(msg, "Line not selectable and still no others selected."); } else { strcpy(msg, "Line not selectable."); } } /* additionally ask for query strings */ if (bEOI == TRUE) { cp = spaLines[nAbsFirstLine+nRelMarked]->cpResult; cp2 = ca; while (bEOI == TRUE && *cp != NUL) { if (strnEQ(cp, "%[", 2)) { cp += 2; for (cp3 = cp; !strniEQ(cp3, "]s", 2); cp3++) ; strncpy(ca3, cp, cp3-cp); ca3[cp3-cp] = NUL; cp = cp3+1; if (*cp == 's') bAllowEmpty = TRUE; else bAllowEmpty = FALSE; cp++; sprintf(msg, "%s: ", ca3); iSelect_Draw(wField, wYSize, wXSize, wYPos, wXPos, nAbsFirstLine, nAbsLastLine, -1, nRelFirstDraw, nRelLastDraw, nLines, sField, title, name, mField, msg, tagbegin, tagend); wrefresh(wField); cp3 = iSelect_InputField(mYSize, mXSize-strlen(msg), mYPos, mXPos+strlen(msg), bAllowEmpty); if (strEQ(cp3, "ESC")) { bEOI = FALSE; spaLines[nAbsFirstLine+nRelMarked]->fSelected = FALSE; strcpy(msg, "Selection cancelled."); continue; } strcpy(msg, ""); strcpy(cp2, cp3); cp2 += strlen(cp3); } else { *cp2++ = *cp++; } } if (bEOI == TRUE) { *cp2 = NUL; if (strNE(spaLines[nAbsFirstLine+nRelMarked]->cpResult, ca)) spaLines[nAbsFirstLine+nRelMarked]->cpResult = strdup(ca); } } } } if (c >= 32 && c <= 126) { /* * a printable character */ if (c == ' ') { if (multiselect) { if (spaLines[nAbsFirstLine+nRelMarked]->fSelectable) { if (spaLines[nAbsFirstLine+nRelMarked]->fSelected == FALSE) spaLines[nAbsFirstLine+nRelMarked]->fSelected = TRUE; else spaLines[nAbsFirstLine+nRelMarked]->fSelected = FALSE; } else { strcpy(msg, "Line not selectable."); } } else { strcpy(msg, "No multi-line selection allowed."); } } else if (c == 'q') { bEOI = TRUE; bQuit = TRUE; } else if (c == 'g') { if (nAbsFirstLine+nRelMarked == nFirstLine) { strcpy(msg, "Already at Begin."); } else { if (nLastLine < (wYSize-1)) { nAbsFirstLine = nFirstLine; nAbsLastLine = nLastLine; nRelFirstDraw = 0; nRelLastDraw = nLastLine-nFirstLine; nRelMarked = 0; } else { nAbsFirstLine = nFirstLine; nAbsLastLine = nFirstLine+(wYSize-1); nRelFirstDraw = 0; nRelLastDraw = (wYSize-1); nRelMarked = 0; } } } else if (c == 'G') { if (nAbsFirstLine+nRelMarked == nLastLine) { strcpy(msg, "Already at End."); } else { if (nLastLine < (wYSize-1)) { nAbsFirstLine = nFirstLine; nAbsLastLine = nLastLine; nRelFirstDraw = 0; nRelLastDraw = nLastLine-nFirstLine; nRelMarked = nLastLine-nFirstLine; } else { nAbsFirstLine = nLastLine-(wYSize-1); nAbsLastLine = nLastLine; nRelFirstDraw = 0; nRelLastDraw = (wYSize-1); nRelMarked = (wYSize-1); } } } else if (c == 'h' || c == 'v') { if (c == 'h') strcpy(msg, "Help Page: Press 'q' to exit"); else strcpy(msg, "Version Page: Press 'q' to exit"); iSelect_Draw(wField, wYSize, wXSize, wYPos, wXPos, nAbsFirstLine, nAbsLastLine, nRelMarked, nRelFirstDraw, nRelLastDraw, nLines, sField, title, name, mField, msg, tagbegin, tagend); wrefresh(wField); hField = newwin(wYSize, wXSize, wYPos, wXPos); werase(hField); if (c == 'h') cpp = iSelect_Help; else cpp = iSelect_README; for (y = 0; y < wYSize && cpp[y] != NULL; y++) { sprintf(ca, cpp[y]); cp = ca; x = 0; while (1) { if ((cp2 = strstr(cp, "<b>")) != NULL) { *cp2 = NUL; wmove(hField, y, x); waddstr(hField, cp); x += strlen(cp); wattrset(hField, A_NORMAL|A_BOLD); cp = cp2+3; cp2 = strstr(cp, "</b>"); *cp2 = NUL; wmove(hField, y, x); waddstr(hField, cp); x += strlen(cp); wattrset(hField, A_NORMAL); cp = cp2+4; } else { wmove(hField, y, x); waddstr(hField, cp); break; } } } wrefresh(hField); while (1) { c = wgetch(wField); c = c & 0xff; /* strip down to 8bit */ if (c == 'q') break; } delwin(hField); nRelFirstDraw = 0; nRelLastDraw = nAbsLastLine-nAbsFirstLine; strcpy(msg, ""); iSelect_Draw(wField, wYSize, wXSize, wYPos, wXPos, nAbsFirstLine, nAbsLastLine, nRelMarked, nRelFirstDraw, nRelLastDraw, nLines, sField, title, name, mField, msg, tagbegin, tagend); #ifndef USE_SLCURSES redrawwin(wField); #endif wrefresh(wField); } else { strcpy(msg, "Invalid key. Press 'h' for Help Page!"); } } } } fflush(stdin); echo(); #ifndef USE_SLCURSES nocrmode(); #endif delwin(wField); if (bQuit) return(-1); else return(nAbsFirstLine+nRelMarked); }