Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
6.6KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include "Log_Entry.H"
  19. // #include "const.h"
  20. #include "debug.h"
  21. Log_Entry::Log_Entry ( )
  22. {
  23. _sa = (char**)malloc( sizeof( char * ) );
  24. *_sa = NULL;
  25. _i = 0;
  26. }
  27. Log_Entry::Log_Entry ( char **sa )
  28. {
  29. _sa = sa;
  30. _i = 0;
  31. if ( _sa )
  32. while ( _sa[ _i ] ) ++_i;
  33. }
  34. Log_Entry::Log_Entry ( const char *s )
  35. {
  36. _i = 0;
  37. _sa = s ? parse_alist( s ) : NULL;
  38. if ( _sa )
  39. while ( _sa[ _i ] ) ++_i;
  40. }
  41. Log_Entry::~Log_Entry ( )
  42. {
  43. if ( ! _sa )
  44. return;
  45. for ( _i = 0; _sa[ _i ]; ++_i )
  46. {
  47. free( _sa[ _i ] );
  48. }
  49. free( _sa );
  50. }
  51. /** remove escapes from string /s/ in-place */
  52. static void
  53. unescape ( char *s )
  54. {
  55. char *r = s;
  56. for ( ; *s; s++, r++ )
  57. {
  58. if ( '\\' == *s )
  59. {
  60. switch ( *(++s) )
  61. {
  62. case 'n':
  63. *r = '\n';
  64. break;
  65. case '"':
  66. *r = '"';
  67. break;
  68. default:
  69. break;
  70. }
  71. }
  72. else
  73. *r = *s;
  74. }
  75. *r = '\0';
  76. }
  77. /** return a dynamically allocated string representing this log entry */
  78. char *
  79. Log_Entry::print ( void ) const
  80. {
  81. /* FIXME: gross over-allocation */
  82. char *r = (char*)malloc( 1024 );
  83. r[0] = 0;
  84. for ( int i = 0; i < size(); ++i )
  85. {
  86. const char *s, *v;
  87. get( i, &s, &v );
  88. /* FIXME: arbitrary limit */
  89. char t[1024];
  90. snprintf( t, sizeof( t ), "%s %s%s", s, v, size() == i + 1 ? "" : " " );
  91. strcat( r, t );
  92. }
  93. char *r2 = (char*)malloc( strlen( r ) + 1 );
  94. strcpy( r2, r );
  95. free( r );
  96. return r2;
  97. }
  98. /** sigh. parse a string of ":name value :name value" pairs into an
  99. * array of strings, one per pair */
  100. // FIXME: doesn't handle the case of :name ":foo bar", nested quotes
  101. // or other things it should.
  102. char **
  103. Log_Entry::parse_alist( const char *s )
  104. {
  105. // FIXME: bogus over allocation...
  106. int tl = strlen( s );
  107. char **r = (char**)malloc( sizeof( char* ) * tl );
  108. bool quote = false;
  109. bool value = false;
  110. const char *c = NULL;
  111. int i = 0;
  112. for ( ; ; s++ )
  113. {
  114. switch ( *s )
  115. {
  116. case '\0':
  117. case ' ':
  118. if ( ! quote && c )
  119. {
  120. if ( ! value )
  121. {
  122. value = true;
  123. break;
  124. }
  125. int l = s - c;
  126. char *pair = (char*)malloc( l + 1 );
  127. /* remove trailing space */
  128. if ( c[ l - 1 ] == ' ' )
  129. --l;
  130. strncpy( pair, c, l );
  131. pair[ l ] = '\0';
  132. r[ i++ ] = pair;
  133. /* split */
  134. strtok( pair, " " );
  135. /* remove quotes */
  136. char *v = pair + strlen( pair ) + 1;
  137. unescape( v );
  138. if ( *v == '"' )
  139. {
  140. // v++;
  141. if ( v[ strlen( v ) - 1 ] != '"' )
  142. WARNING( "invalid quoting in log entry!" );
  143. else
  144. {
  145. v[ strlen( v ) - 1 ] = '\0';
  146. memmove( v, v + 1, strlen( v ) + 1 );
  147. }
  148. }
  149. c = NULL;
  150. }
  151. break;
  152. case ':': /* this is a key */
  153. if ( ! quote && ! c )
  154. {
  155. c = s;
  156. value = false;
  157. }
  158. break;
  159. case '"':
  160. quote = !quote;
  161. break;
  162. case '\\':
  163. s++;
  164. break;
  165. }
  166. if ( *s == '\0' )
  167. break;
  168. }
  169. r[ i ] = NULL;
  170. return r;
  171. }
  172. /** compare elements of dumps s1 and s2, removing those elements
  173. of dst which are not changed from src */
  174. bool
  175. Log_Entry::diff ( Log_Entry *e1, Log_Entry *e2 )
  176. {
  177. if ( ! e1 )
  178. return true;
  179. char **sa1 = e1->_sa;
  180. char **sa2 = e2->_sa;
  181. if ( ! sa1 )
  182. return true;
  183. int w = 0;
  184. for ( int i = 0; sa1[ i ]; ++i )
  185. {
  186. const char *v1 = sa1[ i ] + strlen( sa1[ i ] ) + 1;
  187. const char *v2 = sa2[ i ] + strlen( sa2[ i ] ) + 1;
  188. if ( ! strcmp( sa1[ i ], sa2[ i ] ) && ! strcmp( v1, v2 ) )
  189. {
  190. free( sa2[ i ] );
  191. free( sa1[ i ] );
  192. }
  193. else
  194. {
  195. sa2[ w ] = sa2[ i ];
  196. sa1[ w ] = sa1[ i ];
  197. w++;
  198. }
  199. }
  200. sa1[ w ] = NULL;
  201. sa2[ w ] = NULL;
  202. e1->_i = w;
  203. e2->_i = w;
  204. return w == 0 ? false : true;
  205. }
  206. void
  207. Log_Entry::grow ( )
  208. {
  209. _sa = (char**)realloc( _sa, sizeof( char * ) * (_i + 2) );
  210. _sa[ _i + 1 ] = NULL;
  211. }
  212. int
  213. Log_Entry::size ( void ) const
  214. {
  215. return _i;
  216. }
  217. void
  218. Log_Entry::get ( int n, const char **name, const char **value ) const
  219. {
  220. *name = _sa[ n ];
  221. *value = *name + strlen( *name ) + 1;
  222. }
  223. char **
  224. Log_Entry::sa ( void )
  225. {
  226. return _sa;
  227. /* char **sa = _sa; */
  228. /* // _sa = NULL; */
  229. /* return sa; */
  230. /* } */
  231. }