Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
tuple_formatter.c
Go to the documentation of this file.
1 /*
2  * tuple_formatter.c
3  * Copyright (c) 2007 William Pitcock
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <glib.h>
21 #include <pthread.h>
22 #include <string.h>
23 
24 #include "tuple_compiler.h"
25 #include "tuple_formatter.h"
26 
27 /*
28  * the tuple formatter:
29  *
30  * this is a data-driven meta-language which eventually hopes to be
31  * turing complete.
32  *
33  * language constructs follow the following basic rules:
34  * - begin with ${
35  * - end with }
36  *
37  * language constructs:
38  * - ${field}: prints a field
39  * - ${?field:expr}: evaluates expr if field exists
40  * - ${=field,"value"}: defines field in the currently iterated
41  * tuple as string value of "value"
42  * - ${=field,value}: defines field in the currently iterated
43  * tuple as integer value of "value"
44  * - ${==field,field:expr}: evaluates expr if both fields are the same
45  * - ${!=field,field:expr}: evaluates expr if both fields are not the same
46  * - ${(empty)?field:expr}: evaluates expr if field is empty or does not exist
47  * - %{function:args,arg2,...}: runs function and inserts the result.
48  *
49  * everything else is treated as raw text.
50  * additionally, plugins can add additional instructions and functions!
51  */
52 
53 /*
54  * Compile a tuplez string and cache the result.
55  * This caches the result for the last string, so that
56  * successive calls are sped up.
57  */
58 
59 char * tuple_formatter_process_string (const Tuple * tuple, const char * string)
60 {
61  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
62  pthread_mutex_lock (& mutex);
63 
64  static char *last_string = NULL;
65  static TupleEvalContext *last_ctx = NULL;
66  static TupleEvalNode *last_ev = NULL;
67 
68  if (! last_string || strcmp (string, last_string))
69  {
70  g_free(last_string);
71 
72  if (last_ctx != NULL)
73  {
74  tuple_evalctx_free(last_ctx);
75  tuple_evalnode_free(last_ev);
76  }
77 
78  last_ctx = tuple_evalctx_new();
79  last_string = g_strdup(string);
80  last_ev = tuple_formatter_compile(last_ctx, last_string);
81  }
82 
83  static GString * buf;
84  if (! buf)
85  buf = g_string_sized_new (255);
86 
87  tuple_formatter_eval (last_ctx, last_ev, tuple, buf);
88  tuple_evalctx_reset (last_ctx);
89 
90  char * result = str_get (buf->str);
91 
92  pthread_mutex_unlock (& mutex);
93  return result;
94 }
char * tuple_formatter_process_string(const Tuple *tuple, const char *string)
#define NULL
Definition: core.h:27
static pthread_mutex_t mutex
Definition: eventqueue.c:34
TupleEvalNode * tuple_formatter_compile(TupleEvalContext *ctx, const char *expr)
void tuple_evalctx_reset(TupleEvalContext *ctx)
void tuple_evalnode_free(TupleEvalNode *expr)
TupleEvalContext * tuple_evalctx_new(void)
void tuple_formatter_eval(TupleEvalContext *ctx, TupleEvalNode *expr, const Tuple *tuple, GString *out)
void tuple_evalctx_free(TupleEvalContext *ctx)
char * str_get(const char *str)
Definition: strpool.c:42