/// Parse multiplication and division word36 ParseFactors() { word36 num1 = ParseAtom(); for(;;) { // Skip spaces while(*expr == ' ') expr++; /// Save the operation and position char op = *expr; char* pos = expr; if(op != '/' && op != '*' && op != '%') return num1; expr++; word36 num2 = ParseAtom(); // Perform the saved operation if(op == '/' || op == '%') { // Handle division/modulus by zero if(num2 == 0) { _err = EEE_DIVIDE_BY_ZERO; _err_pos = pos; return 0; } if (op == '/') num1 /= num2; else num1 %= num2; } else num1 *= num2; } }
M4Err ghnt_Read(Atom *s, BitStream *bs, u64 *read) { Atom *a; u64 sr; M4Err e; HintSampleEntryAtom *ptr = (HintSampleEntryAtom *)s; if (ptr == NULL) return M4BadParam; BS_ReadData(bs, ptr->reserved, 6); ptr->dataReferenceIndex = BS_ReadInt(bs, 16); *read += 8; ptr->HintTrackVersion = BS_ReadInt(bs, 16); ptr->LastCompatibleVersion = BS_ReadInt(bs, 16); ptr->MaxPacketSize = BS_ReadInt(bs, 32); *read += 8; while (*read < ptr->size) { e = ParseAtom(&a, bs, &sr); if (e) return e; e = ChainAddEntry(ptr->HintDataTable, a); if (e) return e; *read += a->size; } if (*read != ptr->size) return M4ReadAtomFailed; return M4OK; }
M4Err tx3g_Read(Atom *s, BitStream *bs, u64 *read) { M4Err e; u64 sr; Atom *a; TextSampleEntryAtom *ptr = (TextSampleEntryAtom*)s; BS_ReadData(bs, (unsigned char*)ptr->reserved, 6); ptr->dataReferenceIndex = BS_ReadInt(bs, 16); ptr->displayFlags = BS_ReadInt(bs, 32); ptr->horizontal_justification = BS_ReadInt(bs, 8); ptr->vertical_justification = BS_ReadInt(bs, 8); ptr->back_color = gpp_read_rgba(bs); gpp_read_box(bs, &ptr->default_box); gpp_read_style(bs, &ptr->default_style); *read += 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE; while (*read < ptr->size) { e = ParseAtom(&a, bs, &sr); if (e) return e; *read += a->size; if (a->type==FontTableAtomType) { if (ptr->font_table) DelAtom((Atom *) ptr->font_table); ptr->font_table = (FontTableAtom *)a; } else { DelAtom(a); } } if (*read != ptr->size) return M4ReadAtomFailed; return M4OK; }
void nsAttrValue::ParseStringOrAtom(const nsAString& aValue) { PRUint32 len = aValue.Length(); // Don't bother with atoms if it's an empty string since // we can store those efficently anyway. if (len && len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) { ParseAtom(aValue); } else { SetTo(aValue); } }
void DwRfc1521Tokenizer::ParseToken() { // Assume the field body has already been extracted. That is, we don't // have to watch for the end of the field body or folding. We just // treat any CRs or LFs as white space. mTokenStart = mNextStart; mTokenLength = 0; mTkType = eTkNull; if (mTokenStart >= mString.length()) { return; } // Skip leading space. Also, since control chars are not permitted // in atoms, skip these, too. while (1) { if (mTokenStart >= mString.length()) { return; } if (!isspace(mString[mTokenStart]) && !iscntrl(mString[mTokenStart])) break; ++mTokenStart; } char ch = mString[mTokenStart]; // Quoted string if (ch == '"') { mTkType = eTkQuotedString; ParseQuotedString(); } // Comment else if (ch == '(') { mTkType = eTkComment; ParseComment(); } // Domain literal else if (ch == '[') { mTkType = eTkDomainLiteral; ParseDomainLiteral(); } // Special else if (istspecial(ch)) { mTkType = eTkTspecial; mTokenLength = 1; mToken = mString.substr(mTokenStart, 1); mNextStart = mTokenStart + 1; } // Atom else { mTkType = eTkToken; ParseAtom(); } if (mDebugOut) PrintToken(mDebugOut); }
M4Err amr3_Read(Atom *s, BitStream *bs, u64 *read) { M4Err e; u64 sub_read; AMRSampleEntryAtom *ptr = (AMRSampleEntryAtom *)s; if (ptr == NULL) return M4BadParam; ReadAudioSampleEntry((AudioSampleEntryAtom*)s, bs, read); e = ParseAtom((Atom **)&ptr->amr_info, bs, &sub_read); if (e) return e; *read += sub_read; if (*read != s->size) return M4ReadAtomFailed; return M4OK; }
M4Err h263_Read(Atom *s, BitStream *bs, u64 *read) { M4Err e; u64 sub_read; H263SampleEntryAtom *ptr = (H263SampleEntryAtom *)s; if (ptr == NULL) return M4BadParam; ReadVideoSampleEntry((VisualSampleEntryAtom *)ptr, bs, read); e = ParseAtom((Atom **)&ptr->h263_config, bs, &sub_read); if (e) return e; *read += sub_read; if (*read != ptr->size) return M4ReadAtomFailed; return M4OK; }
M4Err avc1_Read(Atom *s, BitStream *bs, u64 *read) { M4Err e; u64 sr; Atom *a; AVCSampleEntryAtom *ptr = (AVCSampleEntryAtom *)s; ReadVideoSampleEntry((VisualSampleEntryAtom *)ptr, bs, read); while (*read < ptr->size) { e = ParseAtom(&a, bs, &sr); if (e) return e; *read += a->size; e = avc1_AddAtom(ptr, a); if (e) return e; } AVC_RewriteESDescriptor(ptr); return (*read != ptr->size) ? M4ReadAtomFailed : M4OK; }
// Piece ::= Atom [ Repeat ] Instruction* ParsePiece(const char **ppc, ParseInfo &info) { Instruction *i = ParseAtom(ppc, info); if (i) { bool failed = false; Repeat *r = ParseRepeat(ppc, failed, info); if (r) { r->setInstruction(i); i = r; } else if (failed) { delete i; return 0; } } return i; }
//Add this funct to handle incomplete files... //bytesExpected is 0 most of the time. If the file is incomplete, bytesExpected //is the number of bytes missing to parse the atom... M4Err ParseRootAtom(Atom **outAtom, BitStream *bs, u64 *bytesExpected) { M4Err ret; u64 read; //first make sure we can at least get the atom size and type... //18 = size (int32) + type (int32) if (BS_Available(bs) < 8) { *bytesExpected = 8; return M4UncompleteFile; } ret = ParseAtom(outAtom, bs, &read); if (ret == M4UncompleteFile) { *bytesExpected = (*outAtom)->size - read - BS_Available(bs); //rewind our BitStream for next parsing BS_Rewind(bs, read); DelAtom(*outAtom); *outAtom = NULL; } return ret; }
// I kept the same interface, because.. well.. it seemed to make sense at the time. int qtmovie_read(stream_t *file, demux_res_t *demux_res) { // Our parameter object.. qtmovie_t qtmovie; // Our filesize long fileSize; // We haven't found the mdat chunk yet.. g_FoundMdatAtom = 0; g_IsM4AFile = 0; g_IsAppleLossless = 0; g_StopParsing = 0; // construct the stream; qtmovie.stream = file; qtmovie.res = demux_res; // Find the file length.. stream_seek( file, 0, SEEK_END ); fileSize = stream_tell( file ); stream_seek( file, 0, SEEK_SET ); // find the goo inside.. ParseAtom( 0, fileSize, &qtmovie ); // Return our state to the caller.. if ( g_FoundMdatAtom && g_IsM4AFile && g_IsAppleLossless ) return 1; else { // Something didn't go right, so we attempt to clear the allocations that were made during // the failed call, before returning that it failed to the caller. free( demux_res->codecdata ); free( demux_res->time_to_sample ); free( demux_res->sample_byte_size ); return 0; } }
/* * NAME * QuerySCCData - Query for the SCC data on the root window * * SYNOPSIS */ static void QuerySCCDataRGB(Display *dpy, Window root) /* * DESCRIPTION * * RETURNS * None */ { char *property_return, *pChar; int i, j; int count, format, cType, nTables; unsigned long nitems, nbytes_return; Atom MatricesAtom, CorrectAtom; VisualID visualID; XVisualInfo vinfo_template, *vinfo_ret; int nvis; static char *visual_strings[] = { "StaticGray", "GrayScale", "StaticColor", "PseudoColor", "TrueColor", "DirectColor" }; /* * Get Matrices */ MatricesAtom = ParseAtom (dpy, XDCCC_MATRIX_ATOM_NAME, True); if (MatricesAtom != None) { if (_XcmsGetProperty (dpy, root, MatricesAtom, &format, &nitems, &nbytes_return, &property_return) == XcmsFailure) { format = 0; } else if (nitems != 18) { printf ("Property %s had invalid length of %ld\n", XDCCC_MATRIX_ATOM_NAME, nitems); if (property_return) { XFree (property_return); } return; } } if (MatricesAtom == None || !format) { printf ("Could not find property %s\n", XDCCC_MATRIX_ATOM_NAME); } else if (format != 32) { printf ("Data in property %s not in 32 bit format\n", XDCCC_MATRIX_ATOM_NAME); } else { pChar = property_return; printf ("Screen: %d\n", DefaultScreen(dpy)); printf ("Querying property %s\n", XDCCC_MATRIX_ATOM_NAME); printf ("\tXYZtoRGB matrix :\n"); for (i = 0; i < 3; i++) { printf ("\t"); for (j = 0; j < 3; j++) { printf ("\t%8.5f", (long)_XcmsGetElement(format, &pChar, &nitems) / (XcmsFloat) XDCCC_NUMBER); } printf ("\n"); } printf ("\tRGBtoXYZ matrix :\n"); for (i = 0; i < 3; i++) { printf ("\t"); for (j = 0; j < 3; j++) { printf ("\t%8.5f", (long) _XcmsGetElement(format, &pChar, &nitems) / (XcmsFloat) XDCCC_NUMBER); } printf ("\n"); } XFree (property_return); } /* * Get Intensity Tables */ CorrectAtom = XInternAtom (dpy, XDCCC_CORRECT_ATOM_NAME, True); if (CorrectAtom != None) { if (_XcmsGetProperty (dpy, root, CorrectAtom, &format, &nitems, &nbytes_return, &property_return) == XcmsFailure) { format = 0; } else if (nitems <= 0) { printf ("Property %s had invalid length of %ld\n", XDCCC_CORRECT_ATOM_NAME, nitems); if (property_return) { XFree (property_return); } return; } } if (CorrectAtom == None || !format) { printf ("Could not find property %s\n", XDCCC_CORRECT_ATOM_NAME); } else { printf ("\nQuerying property %s\n", XDCCC_CORRECT_ATOM_NAME); pChar = property_return; while (nitems) { switch (format) { case 8: /* * Must have at least: * VisualID0 * VisualID1 * VisualID2 * VisualID3 * type * count * length * intensity1 * intensity2 */ if (nitems < 9) { goto IntensityTblError; } count = 3; break; case 16: /* * Must have at least: * VisualID0 * VisualID3 * type * count * length * intensity1 * intensity2 */ if (nitems < 7) { goto IntensityTblError; } count = 1; break; case 32: /* * Must have at least: * VisualID0 * type * count * length * intensity1 * intensity2 */ if (nitems < 6) { goto IntensityTblError; } count = 0; break; default: goto IntensityTblError; } /* * Get VisualID */ visualID = _XcmsGetElement(format, &pChar, &nitems); /* add the depth, class, and bits info in output */ vinfo_template.visualid = visualID; vinfo_ret = XGetVisualInfo(dpy, VisualIDMask, &vinfo_template, &nvis); while (count--) { visualID = visualID << format; visualID |= _XcmsGetElement(format, &pChar, &nitems); } if (vinfo_ret != NULL) { printf ("\n\tVisualID: 0x%lx class: %s depth: %d bits_per_rgb: %d\n", visualID, visual_strings[vinfo_ret->class], vinfo_ret->depth, vinfo_ret->bits_per_rgb); } else printf ("\n\tVisualID: 0x%lx\n", visualID); XFree(vinfo_ret); cType = _XcmsGetElement(format, &pChar, &nitems); printf ("\ttype: %d\n", cType); nTables = _XcmsGetElement(format, &pChar, &nitems); printf ("\tcount: %d\n", nTables); switch (cType) { case 0: /* Red Table should always exist */ printf ("\tRed Conversion Table:\n"); PrintTableType0(format, &pChar, &nitems); if (nTables > 1) { printf ("\tGreen Conversion Table:\n"); PrintTableType0(format, &pChar, &nitems); printf ("\tBlue Conversion Table:\n"); PrintTableType0(format, &pChar, &nitems); } break; case 1: /* Red Table should always exist */ printf ("\tRed Conversion Table:\n"); PrintTableType1(format, &pChar, &nitems); if (nTables > 1) { printf ("\tGreen Conversion Table:\n"); PrintTableType1(format, &pChar, &nitems); printf ("\tBlue Conversion Table:\n"); PrintTableType1(format, &pChar, &nitems); } break; default: goto IntensityTblError; } }
static void sendOSC_sendtyped(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) { char messageName[MAXPDSTRING]; // char *token; typedArg args[MAX_ARGS]; int i; messageName[0] = '\0'; // empty if(argc>MAX_ARGS) { post ("sendOSC: too many arguments! (max: %d)", MAX_ARGS); return; } // this sock needs to be larger than 0, not >= .. if (x->x_htmsocket > 0) { #ifdef DEBUG post ("sendOSC: type tags? %d", useTypeTags); #endif atom_string(&argv[0], messageName, MAXPDSTRING); // messageName = strtok(targv[0], ","); for (i = 0; i < argc-1; i++) { // token = strtok(targv[i],","); args[i] = ParseAtom(&argv[i+1]); #ifdef DEBUG switch (args[i].type) { case INT_osc: printf("cell-cont: %d\n", args[i].datum.i); break; case FLOAT_osc: printf("cell-cont: %f\n", args[i].datum.f); break; case STRING_osc: printf("cell-cont: %s\n", args[i].datum.s); break; case NOTYPE_osc: printf("unknown type\n"); break; } printf(" type-id: %d\n", args[i].type); #endif } if(WriteMessage(x->x_oscbuf, messageName, i, args)) { post("sendOSC: usage error, write-msg failed: %s", OSC_errorMessage); return; } if(!x->x_bundle) { SendBuffer(x->x_htmsocket, x->x_oscbuf); OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf); } } else post("sendOSC: not connected"); }
struct Expression* ParseRepeatedExpression(const RegexpTokenType* token_stream, int* pos) { struct Expression * atom = NULL; int origpos = *pos; int is_greedy = 1; int lower_bound, upper_bound; atom = ParseAtom(token_stream, pos); if (atom == NULL) { /* All RepeatedExpression terms start with Atom */ goto parse_error; } switch (token_stream[*pos]) { case ZERO_OR_MORE: lower_bound = 0; upper_bound = INFINITY; (*pos)++; break; case ONE_OR_MORE: lower_bound = 1; upper_bound = INFINITY; (*pos)++; break; case ZERO_OR_ONE: lower_bound = 0; upper_bound = 1; (*pos)++; break; case REPEAT_OPEN: { int i, upper_bound_pos; /* Validity check */ for(i=*pos + 1; token_stream[i] != REPEAT_COMMA && token_stream[i] != REPEAT_CLOSE; i++) { if (!isdigit(token_stream[i])) /* including == 0 */ goto parse_error; } if (token_stream[i] == REPEAT_CLOSE) { upper_bound_pos = *pos + 1; } else { upper_bound_pos = i + 1; for(i++; token_stream[i] != REPEAT_CLOSE; i++) { if (!isdigit(token_stream[i])) /* including == 0 */ goto parse_error; } } lower_bound = tokens_to_nat(token_stream + *pos + 1); if (lower_bound == -1) { goto parse_error; } if (token_stream[upper_bound_pos] == REPEAT_CLOSE) { upper_bound = INFINITY; } else { upper_bound = tokens_to_nat(token_stream + upper_bound_pos); if (upper_bound == -1 || upper_bound < lower_bound) { goto parse_error; } } (*pos) = i + 1; break; } default: /* RepeatedExpression := Atom */ return atom; } /* Check for nongreedy mark */ if (token_stream[*pos] == NONGREEDY_MARK) { is_greedy = 0; (*pos)++; } /* All other RepeatedExpression rules */ { struct RepeatedExpression* result = malloc(sizeof(struct RepeatedExpression)); result->base.typecode = REPEATED_EXPRESSION_TYPE; result->base.group_number = NO_GROUP; result->expression_repeated = atom; result->lower_bound = lower_bound; result->upper_bound = upper_bound; result->is_greedy = is_greedy; return (struct Expression*)result; } parse_error: if (atom != NULL) destroy_expression(atom); *pos = origpos; return NULL; }
void DwRfc1521Tokenizer::ParseToken() { // Assume the field body has already been extracted. That is, we don't // have to watch for the end of the field body or folding. We just // treat any CRs or LFs as white space. mTokenStart = mNextStart; mTokenLength = 0; mTkType = eTkNull; // Skip leading space. Also, since control chars are not permitted // in atoms, skip these, too. while(1) { if(mTokenStart >= mString.length()) { return; } if(isnotspaceorcntrl(mString[mTokenStart])) break; ++mTokenStart; } char ch = mString[mTokenStart]; switch(ch) { // Quoted string case '"': mTkType = eTkQuotedString; ParseQuotedString(); break; // Comment case '(': mTkType = eTkComment; ParseComment(); break; // Domain literal case '[': mTkType = eTkDomainLiteral; ParseDomainLiteral(); break; // Special case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '/': case ']': case '?': case '=': mTkType = eTkTspecial; mTokenLength = 1; mToken = mString.substr(mTokenStart, 1); mNextStart = mTokenStart + 1; break; default: mTkType = eTkToken; ParseAtom(); break; } if(mDebugOut) PrintToken(mDebugOut); }
void* NewJulie( Symbol* , short iArgC, Atom* iArgV) { tJulie* me = NIL; double z0Real = 0.0, z0Imag = 0.0, cReal = 0.0, cImag = 0.0; // Take all initialization arguments as passed to us. // This is a little dull for the Julia set, but there is no "natural" alternative switch (iArgC) { default: error("%s: ignoring spurious arguments", kClassName); // fall into next case... case 4: if ( ParseAtom(iArgV + 3, false, true, 0, NIL, kClassName) ) cImag = iArgV[3].a_w.w_float; // fall into next case... case 3: if ( ParseAtom(iArgV + 2, false, true, 0, NIL, kClassName) ) cReal = iArgV[2].a_w.w_float; // fall into next case... case 2: if ( ParseAtom(iArgV + 1, false, true, 0, NIL, kClassName) ) z0Imag = iArgV[1].a_w.w_float; // fall into next case... case 1: if ( ParseAtom(iArgV, false, true, 0, NIL, kClassName) ) z0Real = iArgV[0].a_w.w_float; // fall into next case... case 0: break; } // Let Max/MSP allocate us, our inlets, and outlets. me = (tJulie*) newobject(gObjectClass); if (me == NIL) goto punt; dsp_setup(&(me->coreObject), 4); // All four inlets accept signal vectors outlet_new(me, "signal"); // Two outlets (for real and imaginary outlet_new(me, "signal"); // components of Julia set elements) // // Store initial values // me->zReal = me->z0Real = z0Real; me->zImag = me->z0Imag = z0Imag; me->cReal = cReal; me->cImag = cImag; // // All done // punt: return me; }
static void ParseAtom( int startOffset, int stopOffset, qtmovie_t* qtmovie ) { long currentOffset; int containerAtom; int atomSize; unsigned int atomName; char atomHeader[ 10 ]; if ( g_StopParsing ) return; currentOffset = startOffset; while ( currentOffset < stopOffset) { // Seek to the atom header stream_seek( qtmovie->stream, currentOffset, SEEK_SET ); memset( atomHeader, 0, 10 ); // Read it in.. we only want the atom name & size.. they're always there.. stream_read( qtmovie->stream, 8, atomHeader ); // Now pull out the bits we need.. atomSize = ReadUnsignedInt( &atomHeader[ 0 ] ); atomName = ReadUnsignedInt( &atomHeader[ 4 ] ); // See if it's a container atom.. if it is, then recursively call ParseAtom on it... for ( containerAtom = 0; containerAtom < ( sizeof( g_ContainerAtoms ) / sizeof( unsigned int ) ); containerAtom++ ) { if ( atomName == g_ContainerAtoms[ containerAtom ] ) { ParseAtom( stream_tell( qtmovie->stream ), currentOffset + atomSize, qtmovie ); break; } } if ( atomName == g_FtypAtomName ) { void* pAtomData = GetAtomData( qtmovie, atomSize ); ProcessFtypAtom( pAtomData, qtmovie ); FreeAtomData( pAtomData ); } else if ( atomName == g_StsdAtomName ) { void* pAtomData = GetAtomData( qtmovie, atomSize ); ProcessStsdAtom( pAtomData, qtmovie ); FreeAtomData( pAtomData ); } else if ( atomName == g_SttsAtomName ) { void* pAtomData = GetAtomData( qtmovie, atomSize ); ProcessSttsAtom( pAtomData, qtmovie ); FreeAtomData( pAtomData ); } else if ( atomName == g_StszAtomName ) { void* pAtomData = GetAtomData( qtmovie, atomSize ); ProcessStszAtom( pAtomData, qtmovie ); FreeAtomData( pAtomData ); } else if ( atomName == g_MdatAtomName ) { g_FoundMdatAtom = 1; g_StopParsing = 1; } // If we've got a zero sized atom, then it's all over.. force the offset to trigger a stop. if ( atomSize == 0 ) currentOffset = stopOffset; else currentOffset += atomSize; } // Everything seems to have gone ok... return; }
// Atom ::= "(" Expression ")" | "[" [^] Range "]" | Characters Instruction* ParseAtom(const char **ppc, ParseInfo &info) { Instruction *i = 0; const char *pc = *ppc; switch (*pc) { case '(': { Group::TriState dnl = Group::Inherit; Group::TriState nc = Group::Inherit; Group::TriState ml = Group::Inherit; bool capture = true; bool consume = true; bool invert = false; bool reverse = false; std::string name = ""; ++pc; if (*pc == '?') { ++pc; if (*pc == '#') { // skip everything until ) and from behave as if ParseAtom was // called starting next character ++pc; while (*pc != ')') { if (*pc == '\0') { return 0; } ++pc; } *ppc = ++pc; return ParseAtom(ppc, info); } if (*pc == ':') { capture = false; ++pc; } else if (*pc == '(') { // conditional ++pc; std::string cond; while (*pc != ')') { if (*pc == '\0') { return 0; } cond.push_back(*pc); ++pc; } ++pc; Instruction *ci = ParseExpression(&pc, info); if (!ci || *pc != ')') { if (ci) { delete ci; } return 0; } ++pc; Alternative *alt = dynamic_cast<Alternative*>(ci); Instruction *ifTrue, *ifFalse; if (alt == 0) { ifTrue = ci; ifFalse = 0; } else { ifTrue = alt->first()->clone(); ifFalse = alt->second()->clone(); delete alt; } *ppc = pc; int index = 0; if (sscanf(cond.c_str(), "%d", &index) != 1) { return new Conditional(cond, ifTrue, ifFalse); } else { return new Conditional(index, ifTrue, ifFalse); } } else if (*pc == 'P') { ++pc; if (*pc == '<') { ++pc; while (*pc != '>') { if (*pc == '\0') { return 0; } name.push_back(*pc); ++pc; } ++pc; } else if (*pc == '=') { std::string name; ++pc; while (*pc != ')') { if (*pc == '\0') { return 0; } name.push_back(*pc); ++pc; } ++pc; *ppc = pc; return new Backsubst(name); } else { return 0; } } else if (*pc == '=') { // positive lookahead capture = false; consume = false; ++pc; } else if (*pc == '!') { // negative lookahead capture = false; consume = false; invert = true; ++pc; } else if (*pc == '<') { ++pc; if (*pc == '=') { // positive lookbehind capture = false; consume = false; reverse = true; ++pc; } else if (*pc == '!') { // negative lookbehind capture = false; consume = false; reverse = true; invert = true; ++pc; } else { Log::PrintError("[gcore] rex/ParseAtom: Invalid group format"); return 0; } } else if (*pc == 'i' || *pc == 'm' || *pc == 's' || *pc == '-') { //capture = false; //consume = false; if (*pc == 'i') { // case sensitive off nc = Group::On; ++pc; } if (*pc == 'm') { // multiline on (. matches \r\n) ml = Group::On; ++pc; } if (*pc == 's') { // dot matches new line on dnl = Group::On; ++pc; } if (*pc == '-') { ++pc; if (*pc == 'i') { // case sensitive on nc = Group::Off; ++pc; } if (*pc == 'm') { // multiline off ml = Group::Off; ++pc; } if (*pc == 's') { // dot matches newline off dnl = Group::Off; ++pc; } } if (*pc != ':' && *pc != ')') { // either followed by : or group end (meaning we just want to change exp exec flags) Log::PrintError("[gcore] rex/ParseAtom: Invalid group format"); return 0; } if (*pc == ':') { ++pc; // would having a closing parent here be problematic } else { capture = false; consume = false; } } } int gidx = (capture ? (++(info.numGroups)) : -1); unsigned short flags = (unsigned short)(reverse ? Rex::Reverse : 0); if (*pc != ')') { i = ParseExpression(&pc, info); } if (*pc != ')') { if (i) { delete i; } return 0; } #ifdef _DEBUG_REX Log::PrintDebug("[gcore] rex/ParseAtom: Create group"); Log::SetIndentLevel(Log::GetIndentLevel()+1); Log::PrintDebug("index: %d", gidx); Log::PrintDebug("invert: %d", invert); Log::PrintDebug("consume: %d", consume); Log::PrintDebug("flags: %d", flags); Log::PrintDebug("nc: %d", nc); Log::PrintDebug("ml: %d", ml); Log::PrintDebug("dnl: %d", dnl); Log::PrintDebug("name: %d", name.c_str()); Log::PrintDebug("code: "); if (i) { std::ostringstream oss; Log::SetIndentLevel(Log::GetIndentLevel()+1) i->toStream(oss); Log::PrintDebug(oss.str().c_str()); Log::SetIndentLevel(Log::GetIndentLevel()-1) } Log::SetIndentLevel(Log::GetIndentLevel()-1); #endif i = new Group(gidx, i, !consume, invert, flags, nc, ml, dnl, name); #ifdef _DEBUG_REX Log::PrintDebug("[gcore] rex/ParseAtom: Group created"); #endif ++pc; break; } case '[': { bool inv = false; ++pc; if (*pc == '^') { inv = true; ++pc; } i = ParseRange(&pc, inv, info); if (!i) { return 0; } if (*pc != ']') { Log::PrintError("[gcore] rex/ParseAtom: Invalid character '%c' in expression, expected ']'", *pc); if (i) { delete i; } return 0; } ++pc; break; } default: i = ParseCharacters(&pc, info); if (!i) { i = ParseZerowidth(&pc, info); if (!i) { return 0; } } } *ppc = pc; return i; }