示例#1
0
static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v)
{
 if(_type_&XMLPARSE_TAG_START && current_tags)
   {
    XMLPARSE_ASSERT_STRING(_tag_,k);
    XMLPARSE_ASSERT_STRING(_tag_,v);

    AppendTag(current_tags,k,v);
   }

 return(0);
}
void ModifyTag(TagList *tags,const char *k,const char *v)
{
 int i;

 for(i=0;i<tags->ntags;i++)
    if(!strcmp(tags->k[i],k))
      {
       tags->v[i]=strcpy(realloc(tags->v[i],strlen(v)+1),v);
       return;
      }

 AppendTag(tags,k,v);
}
示例#3
0
文件: subsdec.c 项目: etix/vlc
static text_segment_t* ParseSubtitles( int *pi_align, const char *psz_subtitle )
{
    text_segment_t* p_segment;
    text_segment_t* p_first_segment;
    style_stack_t* p_stack = NULL;
    tag_stack_t* p_tag_stack = NULL;

    //FIXME: Remove initial allocation? Might make the below code more complicated
    p_first_segment = p_segment = text_segment_New( "" );

    bool b_has_align = false;

    /* */
    while( *psz_subtitle )
    {
        /* HTML extensions */
        if( *psz_subtitle == '<' )
        {
            char *psz_tagname = GetTag( &psz_subtitle, false );
            if ( psz_tagname != NULL )
            {
                if( !strcasecmp( psz_tagname, "br" ) )
                {
                    if ( !AppendCharacter( p_segment, '\n' ) )
                    {
                        free( psz_tagname );
                        goto fail;
                    }
                }
                else if( !strcasecmp( psz_tagname, "b" ) )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_BOLD;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                }
                else if( !strcasecmp( psz_tagname, "i" ) )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_ITALIC;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                }
                else if( !strcasecmp( psz_tagname, "u" ) )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_UNDERLINE;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                }
                else if( !strcasecmp( psz_tagname, "s" ) )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_STRIKEOUT;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                }
                else if( !strcasecmp( psz_tagname, "font" ) )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );

                    char* psz_attribute_name;
                    char* psz_attribute_value;

                    while( ( psz_attribute_name = ConsumeAttribute( &psz_subtitle, &psz_attribute_value ) ) )
                    {
                        if ( !strcasecmp( psz_attribute_name, "face" ) )
                        {
                            p_segment->style->psz_fontname = psz_attribute_value;
                            // We don't want to free the attribute value since it has become our fontname
                            psz_attribute_value = NULL;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "family" ) )
                        {
                            p_segment->style->psz_monofontname = psz_attribute_value;
                            psz_attribute_value = NULL;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "size" ) )
                        {
                            int size = atoi( psz_attribute_value );
                            if( size )
                            {
                                p_segment->style->i_font_size = size;
                                p_segment->style->f_font_relsize = STYLE_DEFAULT_REL_FONT_SIZE *
                                        STYLE_DEFAULT_FONT_SIZE / p_segment->style->i_font_size;
                            }
                        }
                        else if ( !strcasecmp( psz_attribute_name, "color" ) )
                        {
                            p_segment->style->i_font_color = vlc_html_color( psz_attribute_value, NULL );
                            p_segment->style->i_features |= STYLE_HAS_FONT_COLOR;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "outline-color" ) )
                        {
                            p_segment->style->i_outline_color = vlc_html_color( psz_attribute_value, NULL );
                            p_segment->style->i_features |= STYLE_HAS_OUTLINE_COLOR;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "shadow-color" ) )
                        {
                            p_segment->style->i_shadow_color = vlc_html_color( psz_attribute_value, NULL );
                            p_segment->style->i_features |= STYLE_HAS_SHADOW_COLOR;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "outline-level" ) )
                        {
                            p_segment->style->i_outline_width = atoi( psz_attribute_value );
                        }
                        else if ( !strcasecmp( psz_attribute_name, "shadow-level" ) )
                        {
                            p_segment->style->i_shadow_width = atoi( psz_attribute_value );
                        }
                        else if ( !strcasecmp( psz_attribute_name, "back-color" ) )
                        {
                            p_segment->style->i_background_color = vlc_html_color( psz_attribute_value, NULL );
                            p_segment->style->i_features |= STYLE_HAS_BACKGROUND_COLOR;
                        }
                        else if ( !strcasecmp( psz_attribute_name, "alpha" ) )
                        {
                            p_segment->style->i_font_alpha = atoi( psz_attribute_value );
                            p_segment->style->i_features |= STYLE_HAS_FONT_ALPHA;
                        }

                        free( psz_attribute_name );
                        free( psz_attribute_value );
                    }
                }
                else
                {
                    // This is an unknown tag. We need to hide it if it's properly closed, and display it otherwise
                    if ( !IsClosed( psz_subtitle, psz_tagname ) )
                    {
                        AppendCharacter( p_segment, '<' );
                        AppendString( p_segment, psz_tagname );
                        AppendCharacter( p_segment, '>' );
                    }
                    else
                    {
                        AppendTag( &p_tag_stack, psz_tagname );
                        // We don't want to free the tagname now, it will be freed when the tag
                        // gets poped from the stack.
                        psz_tagname = NULL;
                    }
                    // In any case, fall through and skip to the closing tag.
                }
                // Skip potential spaces & end tag
                while ( *psz_subtitle && *psz_subtitle != '>' )
                    psz_subtitle++;
                if ( *psz_subtitle == '>' )
                    psz_subtitle++;

                free( psz_tagname );
            }
            else if( !strncmp( psz_subtitle, "</", 2 ))
            {
                char* psz_tagname = GetTag( &psz_subtitle, true );
                if ( psz_tagname != NULL )
                {
                    if ( !strcasecmp( psz_tagname, "b" ) ||
                         !strcasecmp( psz_tagname, "i" ) ||
                         !strcasecmp( psz_tagname, "u" ) ||
                         !strcasecmp( psz_tagname, "s" ) ||
                         !strcasecmp( psz_tagname, "font" ) )
                    {
                        // A closing tag for one of the tags we handle, meaning
                        // we pushed a style onto the stack earlier
                        p_segment = NewTextSegmentPopStyle( p_segment, &p_stack );
                    }
                    else
                    {
                        // Unknown closing tag. If it is closing an unknown tag, ignore it. Otherwise, display it
                        if ( !HasTag( &p_tag_stack, psz_tagname ) )
                        {
                            AppendString( p_segment, "</" );
                            AppendString( p_segment, psz_tagname );
                            AppendCharacter( p_segment, '>' );
                        }
                    }
                    while ( *psz_subtitle == ' ' )
                        psz_subtitle++;
                    if ( *psz_subtitle == '>' )
                        psz_subtitle++;
                    free( psz_tagname );
                }
            }
            else
            {
                /* We have an unknown tag, just append it, and move on.
                 * The rest of the string won't be recognized as a tag, and
                 * we will ignore unknown closing tag
                 */
                AppendCharacter( p_segment, '<' );
                psz_subtitle++;
            }
        }
        /* SSA extensions */
        else if( psz_subtitle[0] == '{' && psz_subtitle[1] == '\\' &&
                 strchr( psz_subtitle, '}' ) )
        {
            /* Check for forced alignment */
            if( !b_has_align &&
                !strncmp( psz_subtitle, "{\\an", 4 ) && psz_subtitle[4] >= '1' && psz_subtitle[4] <= '9' && psz_subtitle[5] == '}' )
            {
                static const int pi_vertical[3] = { SUBPICTURE_ALIGN_BOTTOM, 0, SUBPICTURE_ALIGN_TOP };
                static const int pi_horizontal[3] = { SUBPICTURE_ALIGN_LEFT, 0, SUBPICTURE_ALIGN_RIGHT };
                const int i_id = psz_subtitle[4] - '1';

                b_has_align = true;
                *pi_align = pi_vertical[i_id/3] | pi_horizontal[i_id%3];
            }
            /* TODO fr -> rotation */

            /* Hide {\stupidity} */
            psz_subtitle = strchr( psz_subtitle, '}' ) + 1;
        }
        /* MicroDVD extensions */
        /* FIXME:
         *  - Currently, we don't do difference between X and x, and we should:
         *    Capital Letters applies to the whole text and not one line
         *  - We don't support Position and Coordinates
         *  - We don't support the DEFAULT flag (HEADER)
         */

        else if( psz_subtitle[0] == '{' &&
                 psz_subtitle[2] == ':' && strchr( &psz_subtitle[2], '}' ) )
        {
            const char *psz_tag_end = strchr( &psz_subtitle[2], '}' );
            size_t i_len = psz_tag_end - &psz_subtitle[3];

            if( psz_subtitle[1] == 'Y' || psz_subtitle[1] == 'y' )
            {
                if( psz_subtitle[3] == 'i' )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_ITALIC;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                    psz_subtitle++;
                }
                if( psz_subtitle[3] == 'b' )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_BOLD;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                    psz_subtitle++;
                }
                if( psz_subtitle[3] == 'u' )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_style_flags |= STYLE_UNDERLINE;
                    p_segment->style->i_features |= STYLE_HAS_FLAGS;
                    psz_subtitle++;
                }
            }
            else if( (psz_subtitle[1] == 'C' || psz_subtitle[1] == 'c' )
                    && psz_subtitle[3] == '$' && i_len >= 7 )
            {
                /* Yes, they use BBGGRR, instead of RRGGBB */
                char psz_color[7];
                psz_color[0] = psz_subtitle[8]; psz_color[1] = psz_subtitle[9];
                psz_color[2] = psz_subtitle[6]; psz_color[3] = psz_subtitle[7];
                psz_color[4] = psz_subtitle[4]; psz_color[5] = psz_subtitle[5];
                psz_color[6] = '\0';
                p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                p_segment->style->i_font_color = vlc_html_color( psz_color, NULL );
                p_segment->style->i_features |= STYLE_HAS_FONT_COLOR;
            }
            else if( psz_subtitle[1] == 'F' || psz_subtitle[1] == 'f' )
            {
                p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                p_segment->style->psz_fontname = strndup( &psz_subtitle[3], i_len );
            }
            else if( psz_subtitle[1] == 'S' || psz_subtitle[1] == 's' )
            {
                int size = atoi( &psz_subtitle[3] );
                if( size )
                {
                    p_segment = NewTextSegmentPushStyle( p_segment, &p_stack );
                    p_segment->style->i_font_size = size;
                    p_segment->style->f_font_relsize = STYLE_DEFAULT_REL_FONT_SIZE *
                                STYLE_DEFAULT_FONT_SIZE / p_segment->style->i_font_size;

                }
            }
            /* Currently unsupported since we don't have access to the i_align flag here
            else if( psz_subtitle[1] == 'P' )
            {
                if( psz_subtitle[3] == "1" )
                    i_align = SUBPICTURE_ALIGN_TOP;
                else if( psz_subtitle[3] == "0" )
                    i_align = SUBPICTURE_ALIGN_BOTTOM;
            } */
            // Hide other {x:y} atrocities, notably {o:x}
            psz_subtitle = psz_tag_end + 1;
        }
        else
        {
            if( *psz_subtitle == '\n' || !strncasecmp( psz_subtitle, "\\n", 2 ) )
            {
                if ( !AppendCharacter( p_segment, '\n' ) )
                    goto fail;
                if ( *psz_subtitle == '\n' )
                    psz_subtitle++;
                else
                    psz_subtitle += 2;
            }
            else if( !strncasecmp( psz_subtitle, "\\h", 2 ) )
            {
                if ( !AppendString( p_segment, "\xC2\xA0" ) )
                    goto fail;
                psz_subtitle += 2;
            }
            else
            {
                //FIXME: Highly inneficient
                AppendCharacter( p_segment, *psz_subtitle );
                psz_subtitle++;
            }
        }
    }
    while ( p_stack )
        PopStyle( &p_stack );
    while ( p_tag_stack )
    {
        tag_stack_t *p_tag = p_tag_stack;
        p_tag_stack = p_tag_stack->p_next;
        free( p_tag->psz_tagname );
        free( p_tag );
    }

    return p_first_segment;

fail:
    text_segment_ChainDelete( p_first_segment );
    return NULL;
}
示例#4
0
文件: calendar.c 项目: hoijui/Remind
static int DoCalRem(ParsePtr p, int col)
{
    int oldLen;
    Trigger trig;
    TimeTrig tim;
    Value v;
    int r, err;
    int jul;
    CalEntry *CurCol = CalColumn[col];
    CalEntry *e;
    char const *s, *s2;
    DynamicBuffer buf, obuf, pre_buf;
    Token tok;

    int is_color, col_r, col_g, col_b;

    is_color = 0;
    DBufInit(&buf);
    DBufInit(&pre_buf);

    /* Parse the trigger date and time */
    if ( (r=ParseRem(p, &trig, &tim, 1)) ) {
	FreeTrig(&trig);
	return r;
    }

/* Don't include timed reminders in calendar if -a option supplied. */
    if (DontIssueAts && tim.ttime != NO_TIME) {
	FreeTrig(&trig);
	return OK;
    }
    if (trig.typ == NO_TYPE) {
	FreeTrig(&trig);
	return E_EOLN;
    }
    if (trig.typ == SAT_TYPE) {
	r=DoSatRemind(&trig, &tim, p);
	if (r) {
	    FreeTrig(&trig);
	    if (r == E_EXPIRED) return OK;
	    return r;
	}
	if (!LastTrigValid) {
	    FreeTrig(&trig);
	    return OK;
	}
	r=ParseToken(p, &buf);
	if (r) {
	    FreeTrig(&trig);
	    return r;
	}
	FindToken(DBufValue(&buf), &tok);
	DBufFree(&buf);
	if (tok.type == T_Empty || tok.type == T_Comment) {
	    FreeTrig(&trig);
	    return OK;
	}
	if (tok.type != T_RemType || tok.val == SAT_TYPE) {
	    FreeTrig(&trig);
	    return E_PARSE_ERR;
	}
	if (tok.val == PASSTHRU_TYPE) {
	    r=ParseToken(p, &buf);
	    if (r) return r;
	    if (!DBufLen(&buf)) {
		DBufFree(&buf);
		FreeTrig(&trig);
		return E_EOLN;
	    }
	    StrnCpy(trig.passthru, DBufValue(&buf), PASSTHRU_LEN);
	    DBufFree(&buf);
	}
	trig.typ = tok.val;
	jul = LastTriggerDate;
	if (!LastTrigValid) {
	    FreeTrig(&trig);
	    return OK;
	}
    } else {
	/* Calculate the trigger date */
	jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);
	if (r) {
	    FreeTrig(&trig);
	    return r;
	}
    }

    /* Convert PS and PSF to PASSTHRU */
    if (trig.typ == PS_TYPE) {
	strcpy(trig.passthru, "PostScript");
	trig.typ = PASSTHRU_TYPE;
    } else if (trig.typ == PSF_TYPE) {
	strcpy(trig.passthru, "PSFile");
	trig.typ = PASSTHRU_TYPE;
    }
    if (trig.typ == PASSTHRU_TYPE) {
	if (!PsCal && strcmp(trig.passthru, "COLOR") && strcmp(trig.passthru, "COLOUR")) {
	    FreeTrig(&trig);
	    return OK;
	}
	if (!strcmp(trig.passthru, "COLOR") ||
	    !strcmp(trig.passthru, "COLOUR")) {
	    is_color = 1;
	    /* Strip off the three color numbers */
	    DBufFree(&buf);
	    r=ParseToken(p, &buf);
	    DBufPuts(&pre_buf, DBufValue(&buf));
	    DBufPutc(&pre_buf, ' ');
	    DBufFree(&buf);
	    if (r) {
		FreeTrig(&trig);
		return r;
	    }
	    r=ParseToken(p, &buf);
	    DBufPuts(&pre_buf, DBufValue(&buf));
	    DBufPutc(&pre_buf, ' ');
	    DBufFree(&buf);
	    if (r) {
		FreeTrig(&trig);
		return r;
	    }
	    r=ParseToken(p, &buf);
	    DBufPuts(&pre_buf, DBufValue(&buf));
	    DBufPutc(&pre_buf, ' ');
	    DBufFree(&buf);
	    if (r) {
		FreeTrig(&trig);
		return r;
	    }
	    (void) sscanf(DBufValue(&pre_buf), "%d %d %d",
			  &col_r, &col_g, &col_b);
	    if (col_r < 0) col_r = 0;
	    else if (col_r > 255) col_r = 255;
	    if (col_g < 0) col_g = 0;
	    else if (col_g > 255) col_g = 255;
	    if (col_b < 0) col_b = 0;
	    else if (col_b > 255) col_b = 255;
	    if (!PsCal && !DoSimpleCalendar) {
		DBufFree(&pre_buf);
	    }
	}
    }

    /* If trigger date == today, add it to the current entry */
    DBufInit(&obuf);
    if ((jul == JulianToday) ||
	(DoSimpleCalDelta &&
	 ShouldTriggerReminder(&trig, &tim, jul, &err))) {
	NumTriggered++;

	if (DoSimpleCalendar || tim.ttime != NO_TIME) {
	    /* Suppress time if it's not today or if it's a non-COLOR special */
	    if (jul != JulianToday ||
		(trig.typ == PASSTHRU_TYPE &&
		 strcmp(trig.passthru, "COLOUR") &&
		 strcmp(trig.passthru, "COLOR"))) {
		if (DBufPuts(&obuf, SimpleTime(NO_TIME)) != OK) {
		    DBufFree(&obuf);
		    DBufFree(&pre_buf);
		    FreeTrig(&trig);
		    return E_NO_MEM;
		}
	    } else {
		if (DBufPuts(&obuf, CalendarTime(tim.ttime, tim.duration)) != OK) {
		    DBufFree(&obuf);
		    DBufFree(&pre_buf);
		    FreeTrig(&trig);
		    return E_NO_MEM;
		}
	    }
	}
	if (trig.typ != PASSTHRU_TYPE &&
	    UserFuncExists("calprefix")==1) {
	    char evalBuf[64];
	    sprintf(evalBuf, "calprefix(%d)", trig.priority);
	    s2 = evalBuf;
	    r = EvalExpr(&s2, &v, NULL);
	    if (!r) {
		if (!DoCoerce(STR_TYPE, &v)) {
		    if (DBufPuts(&obuf, v.v.str) != OK) {
			DestroyValue(v);
			DBufFree(&obuf);
			DBufFree(&pre_buf);
			FreeTrig(&trig);
			return E_NO_MEM;
		    }
		}
		DestroyValue(v);
	    }
	}
	oldLen = DBufLen(&obuf);

	/* In -sa mode, run in ADVANCE mode if we're triggering
	 * before the actual date */
	if (jul != JulianToday) {
	    r = DoSubst(p, &obuf, &trig, &tim, jul, ADVANCE_MODE);
	} else {
	    r = DoSubst(p, &obuf, &trig, &tim, jul, CAL_MODE);
	}
	if (r) {
	    DBufFree(&pre_buf);
	    DBufFree(&obuf);
	    FreeTrig(&trig);
	    return r;
	}
	if (DBufLen(&obuf) <= oldLen) {
	    DBufFree(&obuf);
	    DBufFree(&pre_buf);
	    FreeTrig(&trig);
	    return OK;
	}
	if (trig.typ != PASSTHRU_TYPE &&
	    UserFuncExists("calsuffix")==1) {
	    char evalBuf[64];
	    sprintf(evalBuf, "calsuffix(%d)", trig.priority);
	    s2 = evalBuf;
	    r = EvalExpr(&s2, &v, NULL);
	    if (!r) {
		if (!DoCoerce(STR_TYPE, &v)) {
		    if (DBufPuts(&obuf, v.v.str) != OK) {
			DestroyValue(v);
			DBufFree(&obuf);
			DBufFree(&pre_buf);
			FreeTrig(&trig);
			return E_NO_MEM;
		    }
		}
		DestroyValue(v);
	    }
	}
	s = DBufValue(&obuf);
	if (!DoSimpleCalendar) while (isempty(*s)) s++;
	DBufPuts(&pre_buf, s);
	s = DBufValue(&pre_buf);
	e = NEW(CalEntry);
	if (!e) {
	    DBufFree(&obuf);
	    DBufFree(&pre_buf);
	    FreeTrig(&trig);
	    return E_NO_MEM;
	}
#ifdef REM_USE_WCHAR
	e->wc_pos = NULL;
	e->wc_text = NULL;
#endif
	e->is_color = is_color;
	e->r = col_r;
	e->g = col_g;
	e->b = col_b;
	e->text = StrDup(s);
	DBufFree(&obuf);
	DBufFree(&pre_buf);
	if (!e->text) {
	    free(e);
	    FreeTrig(&trig);
	    return E_NO_MEM;
	}
	make_wchar_versions(e);
	DBufInit(&(e->tags));
	DBufPuts(&(e->tags), DBufValue(&(trig.tags)));
	if (SynthesizeTags) {
	    AppendTag(&(e->tags), SynthesizeTag());
	}

	/* Don't need tags any more */
	FreeTrig(&trig);
	e->duration = tim.duration;
	e->priority = trig.priority;
	e->filename = StrDup(FileName);
	if(!e->filename) {
	    free(e);
	    return E_NO_MEM;
	}
	e->lineno = LineNo;

	if (trig.typ == PASSTHRU_TYPE) {
	    StrnCpy(e->passthru, trig.passthru, PASSTHRU_LEN);
	} else {
	    e->passthru[0] = 0;
	}
	e->pos = e->text;
	if (jul == JulianToday) {
	    e->time = tim.ttime;
	} else {
	    e->time = NO_TIME;
	}
	e->next = CurCol;
	CalColumn[col] = e;
	SortCol(&CalColumn[col]);
    }
    return OK;
}