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.

305 lines
5.8KB

  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. #define _LOGGABLE_C
  19. #include "Loggable.H"
  20. #undef _LOGABLE_C
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <stdarg.h>
  24. FILE *Loggable::_fp;
  25. int Loggable::_log_id = 0;
  26. int Loggable::_level = 0;
  27. vector <Loggable *> Loggable::_loggables;
  28. bool
  29. Loggable::open ( const char *filename )
  30. {
  31. if ( ! ( Loggable::_fp = fopen( filename, "a+" ) ) )
  32. {
  33. printf( "Could not open log file for writing!" );
  34. return false;
  35. }
  36. return true;
  37. }
  38. /** sigh. parse a string of ":name value :name value" pairs into an array of strings, one per pair */
  39. static
  40. char **
  41. parse_alist( const char *s )
  42. {
  43. // FIXME: bogus over allocation...
  44. int tl = strlen( s );
  45. char **r = (char**)malloc( sizeof( char* ) * tl );
  46. const char *e = s + tl;
  47. const char *c = NULL;
  48. int i = 0;
  49. for ( ; ; s++ )
  50. {
  51. /* if ( *s == '\n' ) */
  52. /* break; */
  53. // if ( *s == ':' || s == e )
  54. if ( *s == ':' || *s == '\0' )
  55. {
  56. if ( c )
  57. {
  58. int l = s - c;
  59. char *pair = (char*)malloc( l + 1 );
  60. strncpy( pair, c, l );
  61. pair[ l ] = '\0';
  62. r[ i++ ] = pair;
  63. }
  64. c = s;
  65. if ( *s == '\0' )
  66. break;
  67. }
  68. }
  69. r[ i ] = NULL;
  70. return r;
  71. }
  72. void
  73. Loggable::undo ( void )
  74. {
  75. char *buf = new char[ BUFSIZ ];
  76. // fflush( _fp );
  77. fseek( _fp, 0 - BUFSIZ, SEEK_END );
  78. // fseek( _fp, 0, SEEK_SET );
  79. size_t len = fread( buf, 1, BUFSIZ, _fp );
  80. char *s = buf + len - 1;
  81. // FIXME: handle blocks
  82. for ( --s; *s && s > buf; --s )
  83. if ( *s == '\n' )
  84. {
  85. s++;
  86. break;
  87. }
  88. buf[ len ] = NULL;
  89. printf( "undoing \"%s\"\n", s );
  90. int id;
  91. sscanf( s, "%*s %X ", &id );
  92. Loggable *l = find( id );
  93. assert( l );
  94. char command[40];
  95. char *arguments;
  96. sscanf( s, "%*s %*X %s %*[^\n<] << %a[^\n]", command, &arguments );
  97. if ( ! strcmp( command, "set" ) )
  98. {
  99. printf( "got set command.\n" );
  100. char **sa = parse_alist( arguments );
  101. l->set( sa );
  102. }
  103. delete buf;
  104. }
  105. void
  106. Loggable::log ( const char *fmt, ... )
  107. {
  108. va_list args;
  109. if ( fmt )
  110. {
  111. va_start( args, fmt );
  112. vfprintf( _fp, fmt, args );
  113. va_end( args );
  114. }
  115. }
  116. static
  117. void free_sa ( char **sa )
  118. {
  119. char **a = sa;
  120. for ( ; *a; a++ )
  121. free( *a );
  122. free( sa );
  123. }
  124. void
  125. Loggable::log_print( char **o, char **n )
  126. {
  127. if ( n )
  128. for ( ; *n; n++ )
  129. log( "%s%s", *n, *(n + 1) ? " " : "" );
  130. if ( o && *o )
  131. {
  132. if ( n ) log( " << " );
  133. for ( ; *o; o++ )
  134. log( "%s%s", *o, *(o + 1) ? " " : "" );
  135. }
  136. log( "\n" );
  137. }
  138. /** compare elements of dumps s1 and s2, removing those elements
  139. of dst which are not changed from src */
  140. static
  141. bool
  142. log_diff ( char **sa1, char **sa2 )
  143. {
  144. if ( ! sa1 )
  145. return true;
  146. int w = 0;
  147. for ( int i = 0; sa1[ i ]; ++i )
  148. {
  149. if ( ! strcmp( sa1[ i ], sa2[ i ] ) )
  150. {
  151. free( sa2[ i ] );
  152. free( sa1[ i ] );
  153. }
  154. else
  155. {
  156. sa2[ w ] = sa2[ i ];
  157. sa1[ w ] = sa1[ i ];
  158. w++;
  159. }
  160. }
  161. sa1[ w ] = NULL;
  162. sa2[ w ] = NULL;
  163. return w == 0 ? false : true;
  164. }
  165. void
  166. Loggable::log_start ( void )
  167. {
  168. if ( ! _old_state )
  169. _old_state = log_dump();
  170. ++_nest;
  171. }
  172. void
  173. Loggable::log_end ( void )
  174. {
  175. if ( --_nest > 0 )
  176. return;
  177. // assert( _old_state );
  178. char **_new_state = log_dump();
  179. // if ( _old_state )
  180. if ( log_diff( _old_state, _new_state ) )
  181. {
  182. indent();
  183. log( "%s 0x%X set ", class_name(), _id );
  184. log_print( _old_state, _new_state );
  185. }
  186. if ( _new_state )
  187. free_sa( _new_state );
  188. if ( _old_state )
  189. free_sa( _old_state );
  190. _old_state = NULL;
  191. /* if ( _old_state ) */
  192. /* { */
  193. /* free_sa( _old_state ); */
  194. /* _old_state = NULL; */
  195. /* } */
  196. // _old_state = NULL;
  197. }
  198. void
  199. Loggable::log_create ( void )
  200. {
  201. indent();
  202. log( "%s 0x%X new ", class_name(), _id );
  203. char **sa = log_dump();
  204. if ( sa )
  205. {
  206. log_print( NULL, sa );
  207. free_sa( sa );
  208. }
  209. else
  210. log( "\n" );
  211. }
  212. void
  213. Loggable::log_destroy ( void )
  214. {
  215. indent();
  216. log( "%s 0x%X destroy ", class_name(), _id );
  217. char **sa = log_dump();
  218. log_print( sa, NULL );
  219. free_sa( sa );
  220. }