Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
tuple_formatter.c
Go to the documentation of this file.
00001 /*
00002  * tuple_formatter.c
00003  * Copyright (c) 2007 William Pitcock
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  *    this list of conditions, and the following disclaimer.
00010  *
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  *    this list of conditions, and the following disclaimer in the documentation
00013  *    provided with the distribution.
00014  *
00015  * This software is provided "as is" and without any warranty, express or
00016  * implied. In no event shall the authors be liable for any damages arising from
00017  * the use of this software.
00018  */
00019 
00020 #include <glib.h>
00021 #include <pthread.h>
00022 #include <string.h>
00023 
00024 #include "tuple_compiler.h"
00025 #include "tuple_formatter.h"
00026 
00027 /*
00028  * the tuple formatter:
00029  *
00030  * this is a data-driven meta-language which eventually hopes to be
00031  * turing complete.
00032  *
00033  * language constructs follow the following basic rules:
00034  *   - begin with ${
00035  *   - end with }
00036  *
00037  * language constructs:
00038  *   - ${field}: prints a field
00039  *   - ${?field:expr}: evaluates expr if field exists
00040  *   - ${=field,"value"}: defines field in the currently iterated
00041  *                        tuple as string value of "value"
00042  *   - ${=field,value}: defines field in the currently iterated
00043  *                      tuple as integer value of "value"
00044  *   - ${==field,field:expr}: evaluates expr if both fields are the same
00045  *   - ${!=field,field:expr}: evaluates expr if both fields are not the same
00046  *   - ${(empty)?field:expr}: evaluates expr if field is empty or does not exist
00047  *   - %{function:args,arg2,...}: runs function and inserts the result.
00048  *
00049  * everything else is treated as raw text.
00050  * additionally, plugins can add additional instructions and functions!
00051  */
00052 
00053 /*
00054  * Compile a tuplez string and cache the result.
00055  * This caches the result for the last string, so that
00056  * successive calls are sped up.
00057  */
00058 
00059 char * tuple_formatter_process_string (const Tuple * tuple, const char * string)
00060 {
00061     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00062     pthread_mutex_lock (& mutex);
00063 
00064     static char *last_string = NULL;
00065     static TupleEvalContext *last_ctx = NULL;
00066     static TupleEvalNode *last_ev = NULL;
00067 
00068     if (! last_string || strcmp (string, last_string))
00069     {
00070         g_free(last_string);
00071 
00072         if (last_ctx != NULL)
00073         {
00074             tuple_evalctx_free(last_ctx);
00075             tuple_evalnode_free(last_ev);
00076         }
00077 
00078         last_ctx = tuple_evalctx_new();
00079         last_string = g_strdup(string);
00080         last_ev = tuple_formatter_compile(last_ctx, last_string);
00081     }
00082 
00083     static GString * buf;
00084     if (! buf)
00085         buf = g_string_sized_new (255);
00086 
00087     tuple_formatter_eval (last_ctx, last_ev, tuple, buf);
00088     tuple_evalctx_reset (last_ctx);
00089 
00090     char * result = str_get (buf->str);
00091 
00092     pthread_mutex_unlock (& mutex);
00093     return result;
00094 }