Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
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 }