// // Check_Bit_Str: C // // If uncased is TRUE, try to match either upper or lower case. // REBOOL Check_Bit_Str(REBSER *bset, const REBVAL *val, REBOOL uncased) { REBCNT n = VAL_INDEX(val); if (VAL_BYTE_SIZE(val)) { REBYTE *bp = VAL_BIN(val); for (; n < VAL_LEN_HEAD(val); n++) if (Check_Bit(bset, bp[n], uncased)) return TRUE; } else { REBUNI *up = VAL_UNI(val); for (; n < VAL_LEN_HEAD(val); n++) if (Check_Bit(bset, up[n], uncased)) return TRUE; } return FALSE; }
*/ REBCNT Find_Str_Bitset(REBSER *ser, REBCNT head, REBCNT index, REBCNT tail, REBINT skip, REBSER *bset, REBCNT flags) /* ** General purpose find a bitset char in a string. ** ** Supports: forward/reverse with skip, cased/uncase, Unicode/byte. ** ** Skip can be set positive or negative (for reverse). ** ** Flags are set according to ALL_FIND_REFS ** ***********************************************************************/ { REBUNI c1; REBOOL uncase = !GET_FLAG(flags, ARG_FIND_CASE-1); // uncase = case insenstive for (; index >= head && index < tail; index += skip) { c1 = GET_ANY_CHAR(ser, index); //if (uncase && c1 < UNICODE_CASES) { // if (Check_Bit(bset, LO_CASE(c1)) || Check_Bit(bset, UP_CASE(c1))) // return index; //} //else if (Check_Bit(bset, c1, uncase)) return index; if (flags & AM_FIND_MATCH) break; } return NOT_FOUND; }
*/ REBFLG Check_Bit_Str(REBSER *bset, REBVAL *val, REBFLG uncased) /* ** If uncased is TRUE, try to match either upper or lower case. ** ***********************************************************************/ { REBCNT n = VAL_INDEX(val); if (VAL_BYTE_SIZE(val)) { REBYTE *bp = VAL_BIN(val); for (; n < VAL_TAIL(val); n++) if (Check_Bit(bset, bp[n], uncased)) return TRUE; } else { REBUNI *up = VAL_UNI(val); for (; n < VAL_TAIL(val); n++) if (Check_Bit(bset, up[n], uncased)) return TRUE; } return FALSE; }
int Check() { int i,t; for (t=0;t<=10;t++) //Kiem tra So dinh if (n==Num_Dinh[t]) break; if (t>10) return 0; for (i=1;i<=socanh;i++) //Bit if (!Check_Bit(a[i][1],a[i][2])) return 0; for (i=0;i<n;i++) //Kiem tra Noi cnt[i]=0; for (i=1;i<=socanh;i++) { cnt[a[i][1]]++; cnt[a[i][2]]++; } for (i=0;i<n;i++) if (cnt[i]!=t) return 0; return 1; }
*/ static REBCNT Parse_Next_String(REBPARSE *parse, REBCNT index, REBVAL *item, REBCNT depth) /* ** Match the next item in the string ruleset. ** ** If it matches, return the index just past it. ** Otherwise return NOT_FOUND. ** ***********************************************************************/ { // !!! THIS CODE NEEDS CLEANUP AND REWRITE BASED ON OTHER CHANGES REBSER *series = parse->series; REBSER *ser; REBCNT flags = parse->flags | AM_FIND_MATCH | AM_FIND_TAIL; int rewrite_needed; if (Trace_Level) { Trace_Value(7, item); Trace_String(8, STR_SKIP(series, index), series->tail - index); } if (IS_NONE(item)) return index; if (index >= series->tail) return NOT_FOUND; switch (VAL_TYPE(item)) { // Do we match a single character? case REB_CHAR: if (HAS_CASE(parse)) index = (VAL_CHAR(item) == GET_ANY_CHAR(series, index)) ? index+1 : NOT_FOUND; else index = (UP_CASE(VAL_CHAR(item)) == UP_CASE(GET_ANY_CHAR(series, index))) ? index+1 : NOT_FOUND; break; case REB_EMAIL: case REB_STRING: case REB_BINARY: index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), flags); break; // Do we match to a char set? case REB_BITSET: flags = Check_Bit(VAL_SERIES(item), GET_ANY_CHAR(series, index), !HAS_CASE(parse)); index = flags ? index + 1 : NOT_FOUND; break; /* case REB_DATATYPE: // Currently: integer! if (VAL_DATATYPE(item) == REB_INTEGER) { REBCNT begin = index; while (IS_LEX_NUMBER(*str)) str++, index++; if (begin == index) index = NOT_FOUND; } break; */ case REB_TAG: case REB_FILE: // case REB_ISSUE: // !! Can be optimized (w/o COPY) ser = Copy_Form_Value(item, 0); index = Find_Str_Str(series, 0, index, SERIES_TAIL(series), 1, ser, 0, ser->tail, flags); break; case REB_NONE: break; // Parse a sub-rule block: case REB_BLOCK: index = Parse_Rules_Loop(parse, index, VAL_BLK_DATA(item), depth); break; // Do an expression: case REB_PAREN: item = Do_Block_Value_Throw(item); // might GC // old: if (IS_ERROR(item)) Throw_Error(VAL_ERR_OBJECT(item)); index = MIN(index, series->tail); // may affect tail break; default: Trap1(RE_PARSE_RULE, item); } return index; }
*/ REBSER *Parse_String(REBSER *series, REBCNT index, REBVAL *rules, REBCNT flags) /* ***********************************************************************/ { REBCNT tail = series->tail; REBSER *blk; REBSER *set; REBCNT begin; REBCNT end; REBOOL skip_spaces = !(flags & PF_ALL); REBUNI uc; blk = BUF_EMIT; // shared series RESET_SERIES(blk); // String of delimiters or single character: if (IS_STRING(rules) || IS_CHAR(rules)) { begin = Find_Max_Bit(rules); if (begin <= ' ') begin = ' ' + 1; set = Make_Bitset(begin); Set_Bits(set, rules, TRUE); } // None, so use defaults ",;": else { set = Make_Bitset(1+MAX(',',';')); Set_Bit(set, ',', TRUE); Set_Bit(set, ';', TRUE); } SAVE_SERIES(set); // If required, make space delimiters too: if (skip_spaces) { for (uc = 1; uc <= ' '; uc++) Set_Bit(set, uc, TRUE); } while (index < tail) { if (--Eval_Count <= 0 || Eval_Signals) Do_Signals(); // Skip whitespace if not /all refinement: if (skip_spaces) { uc = 0; for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (!IS_WHITE(uc)) break; } } else uc = GET_ANY_CHAR(series, index); // prefetch if (index < tail) { // Handle quoted strings (in a simple way): if (uc == '"') { begin = ++index; // eat quote for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (uc == '"') break; } end = index; if (index < tail) index++; } // All other tokens: else { begin = index; for (; index < tail; index++) { if (Check_Bit(set, GET_ANY_CHAR(series, index), !(flags & PF_CASE))) break; } end = index; } // Skip trailing spaces: if (skip_spaces) for (; index < tail; index++) { uc = GET_ANY_CHAR(series, index); if (!IS_WHITE(uc)) break; } // Check for and remove separator: if (Check_Bit(set, GET_ANY_CHAR(series, index), !(flags & PF_CASE))) index++; // Append new string: Set_String(Append_Value(blk), Copy_String(series, begin, end - begin)); } } UNSAVE_SERIES(set); return Copy_Block(blk, 0); }