Beispiel #1
0
static void plistFindTagsUnderKey (xmlNode *node,
				   const struct sTagXpathRecurSpec *spec,
				   xmlXPathContext *ctx,
				   void *userData)
{
	xmlNode *current;
	xmlNode *prev;
	stringList *queue;
	vString* path;
	vString* v;
	int c;

	queue = stringListNew ();
	current = node;
	for (current = node; current; current = current->parent)
	{
		if (isCompoundElement (current)
		    && (prev = getPrevKeyElement (current)))
		{
			char* parent = (char *)xmlNodeGetContent (prev);
			if (parent)
			{
				v = vStringNewInit (parent);
				stringListAdd (queue, v);
				xmlFree (parent);
			}
		}
	}

	path = vStringNew ();
	while ((c = stringListCount (queue)) > 0)
	{
		v = stringListLast (queue);
		vStringCat (path, v);
		vStringDelete (v);
		stringListRemoveLast (queue);
		if (c != 1)
			vStringPut (path, '.');
	}
	stringListDelete (queue);

	findXMLTags (ctx, node,
		     plistXpathTableTable + TABLE_TEXT,
		     PlistKinds,
		     (vStringLength (path) > 0)? vStringValue (path): NULL);

	vStringDelete (path);
}
Beispiel #2
0
static void findRubyTags (void)
{
    const unsigned char *line;
    boolean inMultiLineComment = FALSE;

    nesting = stringListNew ();

    /* FIXME: this whole scheme is wrong, because Ruby isn't line-based.
    * You could perfectly well write:
    *
    *  def
    *  method
    *   puts("hello")
    *  end
    *
    * if you wished, and this function would fail to recognize anything.
    */
    while ((line = fileReadLine ()) != NULL)
    {
        const unsigned char *cp = line;

        if (canMatch (&cp, "=begin"))
        {
            inMultiLineComment = TRUE;
            continue;
        }
        if (canMatch (&cp, "=end"))
        {
            inMultiLineComment = FALSE;
            continue;
        }

        skipWhitespace (&cp);

        /* Avoid mistakenly starting a scope for modifiers such as
        *
        *   return if <exp>
        *
        * FIXME: this is fooled by code such as
        *
        *   result = if <exp>
        *               <a>
        *            else
        *               <b>
        *            end
        *
        * FIXME: we're also fooled if someone does something heinous such as
        *
        *   puts("hello") \
        *       unless <exp>
        */
        if (canMatch (&cp, "case") || canMatch (&cp, "for") ||
            canMatch (&cp, "if") || canMatch (&cp, "unless") ||
            canMatch (&cp, "while"))
        {
            enterUnnamedScope ();
        }

        /*
        * "module M", "class C" and "def m" should only be at the beginning
        * of a line.
        */
        if (canMatch (&cp, "module"))
        {
            readAndEmitTag (&cp, K_MODULE);
        }
        else if (canMatch (&cp, "class"))
        {
            readAndEmitTag (&cp, K_CLASS);
        }
        else if (canMatch (&cp, "def"))
        {
            readAndEmitTag (&cp, K_METHOD);
        }

        while (*cp != '\0')
        {
            /* FIXME: we don't cope with here documents,
            * or regular expression literals, or ... you get the idea.
            * Hopefully, the restriction above that insists on seeing
            * definitions at the starts of lines should keep us out of
            * mischief.
            */
            if (inMultiLineComment || isspace (*cp))
            {
                ++cp;
            }
            else if (*cp == '#')
            {
                /* FIXME: this is wrong, but there *probably* won't be a
                * definition after an interpolated string (where # doesn't
                * mean 'comment').
                */
                break;
            }
            else if (canMatch (&cp, "begin") || canMatch (&cp, "do"))
            {
                enterUnnamedScope ();
            }
            else if (canMatch (&cp, "end") && stringListCount (nesting) > 0)
            {
                /* Leave the most recent scope. */
                vStringDelete (stringListLast (nesting));
                stringListRemoveLast (nesting);
            }
            else if (*cp == '"')
            {
                /* Skip string literals.
                 * FIXME: should cope with escapes and interpolation.
                 */
                do {
                    ++cp;
                } while (*cp != 0 && *cp != '"');
            }
            else if (*cp != '\0')
            {
                do
                    ++cp;
                while (isalnum (*cp) || *cp == '_');
            }
        }
    }
    stringListDelete (nesting);
}