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.

247 lines
5.4KB

  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. // const char *e = s + tl;
  88. const char *c = NULL;
  89. int i = 0;
  90. for ( ; ; s++ )
  91. {
  92. /* if ( *s == '\n' ) */
  93. /* break; */
  94. // if ( *s == ':' || s == e )
  95. if ( *s == ':' || *s == '\0' )
  96. {
  97. if ( c )
  98. {
  99. int l = s - c;
  100. char *pair = (char*)malloc( l + 1 );
  101. /* remove trailing space */
  102. if ( c[ l - 1 ] == ' ' )
  103. --l;
  104. strncpy( pair, c, l );
  105. pair[ l ] = '\0';
  106. r[ i++ ] = pair;
  107. /* split */
  108. strtok( pair, " " );
  109. /* remove quotes */
  110. char *v = pair + strlen( pair ) + 1;
  111. unescape( v );
  112. if ( *v == '"' )
  113. {
  114. // v++;
  115. if ( v[ strlen( v ) - 1 ] != '"' )
  116. WARNING( "invalid quoting in log entry!" );
  117. else
  118. {
  119. v[ strlen( v ) - 1 ] = '\0';
  120. memmove( v, v + 1, strlen( v ) + 1 );
  121. }
  122. }
  123. }
  124. c = s;
  125. if ( *s == '\0' )
  126. break;
  127. }
  128. }
  129. r[ i ] = NULL;
  130. return r;
  131. }
  132. /** compare elements of dumps s1 and s2, removing those elements
  133. of dst which are not changed from src */
  134. bool
  135. Log_Entry::diff ( Log_Entry *e1, Log_Entry *e2 )
  136. {
  137. if ( ! e1 )
  138. return true;
  139. char **sa1 = e1->_sa;
  140. char **sa2 = e2->_sa;
  141. if ( ! sa1 )
  142. return true;
  143. int w = 0;
  144. for ( int i = 0; sa1[ i ]; ++i )
  145. {
  146. const char *v1 = sa1[ i ] + strlen( sa1[ i ] ) + 1;
  147. const char *v2 = sa2[ i ] + strlen( sa2[ i ] ) + 1;
  148. if ( ! strcmp( sa1[ i ], sa2[ i ] ) && ! strcmp( v1, v2 ) )
  149. {
  150. free( sa2[ i ] );
  151. free( sa1[ i ] );
  152. }
  153. else
  154. {
  155. sa2[ w ] = sa2[ i ];
  156. sa1[ w ] = sa1[ i ];
  157. w++;
  158. }
  159. }
  160. sa1[ w ] = NULL;
  161. sa2[ w ] = NULL;
  162. e1->_i = w;
  163. e2->_i = w;
  164. return w == 0 ? false : true;
  165. }
  166. void
  167. Log_Entry::grow ( )
  168. {
  169. _sa = (char**)realloc( _sa, sizeof( char * ) * (_i + 2) );
  170. _sa[ _i + 1 ] = NULL;
  171. }
  172. int
  173. Log_Entry::size ( void ) const
  174. {
  175. return _i;
  176. }
  177. void
  178. Log_Entry::get ( int n, const char **name, const char **value ) const
  179. {
  180. *name = _sa[ n ];
  181. *value = *name + strlen( *name ) + 1;
  182. }
  183. char **
  184. Log_Entry::sa ( void )
  185. {
  186. return _sa;
  187. /* char **sa = _sa; */
  188. /* // _sa = NULL; */
  189. /* return sa; */
  190. /* } */
  191. }