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.

267 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. printf( "%s\n", v );
  129. c = NULL;
  130. }
  131. break;
  132. case ':': /* this is a key */
  133. if ( ! quote && ! c )
  134. {
  135. c = s;
  136. value = false;
  137. }
  138. break;
  139. case '"':
  140. quote = !quote;
  141. break;
  142. case '\\':
  143. s++;
  144. break;
  145. }
  146. if ( *s == '\0' )
  147. break;
  148. }
  149. r[ i ] = NULL;
  150. return r;
  151. }
  152. /** compare elements of dumps s1 and s2, removing those elements
  153. of dst which are not changed from src */
  154. bool
  155. Log_Entry::diff ( Log_Entry *e1, Log_Entry *e2 )
  156. {
  157. if ( ! e1 )
  158. return true;
  159. char **sa1 = e1->_sa;
  160. char **sa2 = e2->_sa;
  161. if ( ! sa1 )
  162. return true;
  163. int w = 0;
  164. for ( int i = 0; sa1[ i ]; ++i )
  165. {
  166. const char *v1 = sa1[ i ] + strlen( sa1[ i ] ) + 1;
  167. const char *v2 = sa2[ i ] + strlen( sa2[ i ] ) + 1;
  168. if ( ! strcmp( sa1[ i ], sa2[ i ] ) && ! strcmp( v1, v2 ) )
  169. {
  170. free( sa2[ i ] );
  171. free( sa1[ i ] );
  172. }
  173. else
  174. {
  175. sa2[ w ] = sa2[ i ];
  176. sa1[ w ] = sa1[ i ];
  177. w++;
  178. }
  179. }
  180. sa1[ w ] = NULL;
  181. sa2[ w ] = NULL;
  182. e1->_i = w;
  183. e2->_i = w;
  184. return w == 0 ? false : true;
  185. }
  186. void
  187. Log_Entry::grow ( )
  188. {
  189. _sa = (char**)realloc( _sa, sizeof( char * ) * (_i + 2) );
  190. _sa[ _i + 1 ] = NULL;
  191. }
  192. int
  193. Log_Entry::size ( void ) const
  194. {
  195. return _i;
  196. }
  197. void
  198. Log_Entry::get ( int n, const char **name, const char **value ) const
  199. {
  200. *name = _sa[ n ];
  201. *value = *name + strlen( *name ) + 1;
  202. }
  203. char **
  204. Log_Entry::sa ( void )
  205. {
  206. return _sa;
  207. /* char **sa = _sa; */
  208. /* // _sa = NULL; */
  209. /* return sa; */
  210. /* } */
  211. }