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.

265 lines
6.0KB

  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 "util/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. /** sigh. parse a string of ":name value :name value" pairs into an
  78. * array of strings, one per pair */
  79. // FIXME: doesn't handle the case of :name ":foo bar", nested quotes
  80. // or other things it should.
  81. char **
  82. Log_Entry::parse_alist( const char *s )
  83. {
  84. // FIXME: bogus over allocation...
  85. int tl = strlen( s );
  86. char **r = (char**)malloc( sizeof( char* ) * tl );
  87. bool quote = false;
  88. bool value = false;
  89. const char *c = NULL;
  90. int i = 0;
  91. for ( ; ; s++ )
  92. {
  93. switch ( *s )
  94. {
  95. case '\0':
  96. case ' ':
  97. if ( ! quote && c )
  98. {
  99. if ( ! value )
  100. {
  101. value = true;
  102. break;
  103. }
  104. int l = s - c;
  105. char *pair = (char*)malloc( l + 1 );
  106. /* remove trailing space */
  107. if ( c[ l - 1 ] == ' ' )
  108. --l;
  109. strncpy( pair, c, l );
  110. pair[ l ] = '\0';
  111. r[ i++ ] = pair;
  112. /* split */
  113. strtok( pair, " " );
  114. /* remove quotes */
  115. char *v = pair + strlen( pair ) + 1;
  116. unescape( v );
  117. if ( *v == '"' )
  118. {
  119. // v++;
  120. if ( v[ strlen( v ) - 1 ] != '"' )
  121. WARNING( "invalid quoting in log entry!" );
  122. else
  123. {
  124. v[ strlen( v ) - 1 ] = '\0';
  125. memmove( v, v + 1, strlen( v ) + 1 );
  126. }
  127. }
  128. c = NULL;
  129. }
  130. break;
  131. case ':': /* this is a key */
  132. if ( ! quote && ! c )
  133. {
  134. c = s;
  135. value = false;
  136. }
  137. break;
  138. case '"':
  139. quote = !quote;
  140. break;
  141. case '\\':
  142. s++;
  143. break;
  144. }
  145. if ( *s == '\0' )
  146. break;
  147. }
  148. r[ i ] = NULL;
  149. return r;
  150. }
  151. /** compare elements of dumps s1 and s2, removing those elements
  152. of dst which are not changed from src */
  153. bool
  154. Log_Entry::diff ( Log_Entry *e1, Log_Entry *e2 )
  155. {
  156. if ( ! e1 )
  157. return true;
  158. char **sa1 = e1->_sa;
  159. char **sa2 = e2->_sa;
  160. if ( ! sa1 )
  161. return true;
  162. int w = 0;
  163. for ( int i = 0; sa1[ i ]; ++i )
  164. {
  165. const char *v1 = sa1[ i ] + strlen( sa1[ i ] ) + 1;
  166. const char *v2 = sa2[ i ] + strlen( sa2[ i ] ) + 1;
  167. if ( ! strcmp( sa1[ i ], sa2[ i ] ) && ! strcmp( v1, v2 ) )
  168. {
  169. free( sa2[ i ] );
  170. free( sa1[ i ] );
  171. }
  172. else
  173. {
  174. sa2[ w ] = sa2[ i ];
  175. sa1[ w ] = sa1[ i ];
  176. w++;
  177. }
  178. }
  179. sa1[ w ] = NULL;
  180. sa2[ w ] = NULL;
  181. e1->_i = w;
  182. e2->_i = w;
  183. return w == 0 ? false : true;
  184. }
  185. void
  186. Log_Entry::grow ( )
  187. {
  188. _sa = (char**)realloc( _sa, sizeof( char * ) * (_i + 2) );
  189. _sa[ _i + 1 ] = NULL;
  190. }
  191. int
  192. Log_Entry::size ( void ) const
  193. {
  194. return _i;
  195. }
  196. void
  197. Log_Entry::get ( int n, const char **name, const char **value ) const
  198. {
  199. *name = _sa[ n ];
  200. *value = *name + strlen( *name ) + 1;
  201. }
  202. char **
  203. Log_Entry::sa ( void )
  204. {
  205. return _sa;
  206. /* char **sa = _sa; */
  207. /* // _sa = NULL; */
  208. /* return sa; */
  209. /* } */
  210. }