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.

240 lines
5.3KB

  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. Log_Entry::Log_Entry ( )
  20. {
  21. _sa = (char**)malloc( sizeof( char * ) );
  22. *_sa = NULL;
  23. _i = 0;
  24. }
  25. Log_Entry::Log_Entry ( char **sa )
  26. {
  27. _sa = sa;
  28. _i = 0;
  29. if ( _sa )
  30. while ( _sa[ _i ] ) ++_i;
  31. }
  32. Log_Entry::Log_Entry ( const char *s )
  33. {
  34. _i = 0;
  35. _sa = s ? parse_alist( s ) : NULL;
  36. if ( _sa )
  37. while ( _sa[ _i ] ) ++_i;
  38. }
  39. Log_Entry::~Log_Entry ( )
  40. {
  41. if ( ! _sa )
  42. return;
  43. for ( _i = 0; _sa[ _i ]; ++_i )
  44. {
  45. free( _sa[ _i ] );
  46. }
  47. free( _sa );
  48. }
  49. /** remove escapes from string /s/ in-place */
  50. static void
  51. unescape ( char *s )
  52. {
  53. char *r = s;
  54. for ( ; *s; s++, r++ )
  55. {
  56. if ( '\\' == *s )
  57. {
  58. switch ( *(++s) )
  59. {
  60. case 'n':
  61. *r = '\n';
  62. break;
  63. case '"':
  64. *r = '"';
  65. break;
  66. default:
  67. break;
  68. }
  69. }
  70. else
  71. *r = *s;
  72. }
  73. *r = '\0';
  74. }
  75. /** sigh. parse a string of ":name value :name value" pairs into an
  76. * array of strings, one per pair */
  77. // FIXME: doesn't handle the case of :name ":foo bar", nested quotes
  78. // or other things it should.
  79. char **
  80. Log_Entry::parse_alist( const char *s )
  81. {
  82. // FIXME: bogus over allocation...
  83. int tl = strlen( s );
  84. char **r = (char**)malloc( sizeof( char* ) * tl );
  85. // const char *e = s + tl;
  86. const char *c = NULL;
  87. int i = 0;
  88. for ( ; ; s++ )
  89. {
  90. /* if ( *s == '\n' ) */
  91. /* break; */
  92. // if ( *s == ':' || s == e )
  93. if ( *s == ':' || *s == '\0' )
  94. {
  95. if ( c )
  96. {
  97. int l = s - c;
  98. char *pair = (char*)malloc( l + 1 );
  99. /* remove trailing space */
  100. if ( c[ l - 1 ] == ' ' )
  101. --l;
  102. strncpy( pair, c, l );
  103. pair[ l ] = '\0';
  104. r[ i++ ] = pair;
  105. /* split */
  106. strtok( pair, " " );
  107. /* remove quotes */
  108. char *v = pair + strlen( pair ) + 1;
  109. unescape( v );
  110. if ( *v == '"' )
  111. {
  112. // v++;
  113. if ( v[ strlen( v ) - 1 ] != '"' )
  114. WARNING( "invalid quoting in log entry!" );
  115. else
  116. {
  117. v[ strlen( v ) - 1 ] = '\0';
  118. memmove( v, v + 1, strlen( v ) + 1 );
  119. }
  120. }
  121. }
  122. c = s;
  123. if ( *s == '\0' )
  124. break;
  125. }
  126. }
  127. r[ i ] = NULL;
  128. return r;
  129. }
  130. /** compare elements of dumps s1 and s2, removing those elements
  131. of dst which are not changed from src */
  132. bool
  133. Log_Entry::diff ( Log_Entry *e1, Log_Entry *e2 )
  134. {
  135. char **sa1 = e1->_sa;
  136. char **sa2 = e2->_sa;
  137. if ( ! sa1 )
  138. return true;
  139. int w = 0;
  140. for ( int i = 0; sa1[ i ]; ++i )
  141. {
  142. const char *v1 = sa1[ i ] + strlen( sa1[ i ] ) + 1;
  143. const char *v2 = sa2[ i ] + strlen( sa2[ i ] ) + 1;
  144. if ( ! strcmp( sa1[ i ], sa2[ i ] ) && ! strcmp( v1, v2 ) )
  145. {
  146. free( sa2[ i ] );
  147. free( sa1[ i ] );
  148. }
  149. else
  150. {
  151. sa2[ w ] = sa2[ i ];
  152. sa1[ w ] = sa1[ i ];
  153. w++;
  154. }
  155. }
  156. sa1[ w ] = NULL;
  157. sa2[ w ] = NULL;
  158. e1->_i = w;
  159. e2->_i = w;
  160. return w == 0 ? false : true;
  161. }
  162. void
  163. Log_Entry::grow ( )
  164. {
  165. _sa = (char**)realloc( _sa, sizeof( char * ) * (_i + 2) );
  166. _sa[ _i + 1 ] = NULL;
  167. }
  168. int
  169. Log_Entry::size ( void ) const
  170. {
  171. return _i;
  172. }
  173. void
  174. Log_Entry::get ( int n, const char **name, const char **value ) const
  175. {
  176. *name = _sa[ n ];
  177. *value = *name + strlen( *name ) + 1;
  178. }
  179. char **
  180. Log_Entry::sa ( void )
  181. {
  182. return _sa;
  183. /* char **sa = _sa; */
  184. /* // _sa = NULL; */
  185. /* return sa; */
  186. /* } */
  187. }