Login
Check-in [4bc926851e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplified fsl_outputer by removing one level of indirection, replacing its state member (of type fsl_state) with a simple void pointer. The older level of indirection has never proven to be useful.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4bc926851ee9cfb58fbe112faf92d84ed0e1d778
User & Date: stephan 2021-10-13 09:42:19.611
Context
2021-10-13
09:51
Changed return semantics of fsl_cx_flag_set(). Seems more useful this way. check-in: d509da4728 user: stephan tags: trunk
09:42
Simplified fsl_outputer by removing one level of indirection, replacing its state member (of type fsl_state) with a simple void pointer. The older level of indirection has never proven to be useful. check-in: 4bc926851e user: stephan tags: trunk
09:35
Initial implementation of a new callback interface for fsl_annotate() which moves the burnden of formatting to the caller (with an implementation provided which formats like fossil does). check-in: 24bc694bf8 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to f-apps/f-annotate.c.
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    if(rc) goto end;
  }
  if((rc=fcli_has_unused_args(false))) goto end;
  if(App.opt.limit<0) App.opt.limit = 0;
  if(ignoreAllSpace) App.opt.spacePolicy = 1;
  else if(ignoreEOLSpace) App.opt.spacePolicy = -1;
  fsl_outputer myOut = fsl_outputer_FILE;
  myOut.state.state = stdout;
  App.opt.out = fsl_annotate_step_f_output_f;
  App.opt.outState = &myOut;
  rc = fsl_annotate(f, &App.opt);

  end:
  fsl_buffer_clear(&fnamebuf);
  return fcli_end_of_main(rc)







|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    if(rc) goto end;
  }
  if((rc=fcli_has_unused_args(false))) goto end;
  if(App.opt.limit<0) App.opt.limit = 0;
  if(ignoreAllSpace) App.opt.spacePolicy = 1;
  else if(ignoreEOLSpace) App.opt.spacePolicy = -1;
  fsl_outputer myOut = fsl_outputer_FILE;
  myOut.state = stdout;
  App.opt.out = fsl_annotate_step_f_output_f;
  App.opt.outState = &myOut;
  rc = fsl_annotate(f, &App.opt);

  end:
  fsl_buffer_clear(&fnamebuf);
  return fcli_end_of_main(rc)
Changes to include/fossil-scm/fossil-util.h.
324
325
326
327
328
329
330
331


332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
*/
struct fsl_outputer {
  /**
     Output channel.
  */
  fsl_output_f out;
  /**
     flush() implementation.


  */
  fsl_flush_f flush;
  /**
     State to be used when calling this->out(), namely:
     this->out( this->state.state, ... ).

     Potential TODO: replace this with a simple (void*). The extra
     level of encapsulation here has never proven to be necessary.
  */
  fsl_state state;
};
/** Empty-initialized fsl_outputer instance. */
#define fsl_outputer_empty_m {NULL,NULL,fsl_state_empty_m}
/**
   Empty-initialized fsl_outputer instance, intended for
   copy-initializing.
*/
FSL_EXPORT const fsl_outputer fsl_outputer_empty;

/**
   A fsl_outputer instance which is initialized to output to a
   (FILE*). To use it, this value then set the copy's state.state
   member to an opened-for-write (FILE*) handle. By default it will
   use stdout. Its finalizer (if called!) will fclose(3)
   self.state.state if self.state.state is not one of (stdout,
   stderr). To disable the closing behaviour (and not close the
   file), set self.state.finalize.f to NULL (but then be sure that
   the file handle outlives this object and to fclose(3) it when
   finished with it).
*/
FSL_EXPORT const fsl_outputer fsl_outputer_FILE;

/**
   fsl_outputer initializer which uses fsl_flush_f_FILE(),
   fsl_output_f_FILE(), and fsl_finalizer_f_FILE().
*/
#define fsl_outputer_FILE_m {                   \
    fsl_output_f_FILE,                          \
      fsl_flush_f_FILE,                         \
      {/*state*/                                \
        NULL,                                   \
        {NULL,fsl_finalizer_f_FILE}             \
      }                                         \
  }
/**
   Generic stateful alloc/free/realloc() interface.

   Implementations must behave as follows:

   - If 0==n then semantically behave like free(3) and return







|
>
>




|
<
<
<

|


|








|

|
<
<
<
<
<









|
<
|
<
<







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354





355
356
357
358
359
360
361
362
363
364

365


366
367
368
369
370
371
372
*/
struct fsl_outputer {
  /**
     Output channel.
  */
  fsl_output_f out;
  /**
     flush() implementation. This may be NULL for most uses of this
     class. Cases which specifically require it must document that
     requirement so.
  */
  fsl_flush_f flush;
  /**
     State to be used when calling this->out(), namely:
     this->out( this->state, ... ) and this->flush(this->state).



  */
  void * state;
};
/** Empty-initialized fsl_outputer instance. */
#define fsl_outputer_empty_m {NULL,NULL,NULL}
/**
   Empty-initialized fsl_outputer instance, intended for
   copy-initializing.
*/
FSL_EXPORT const fsl_outputer fsl_outputer_empty;

/**
   A fsl_outputer instance which is initialized to output to a
   (FILE*). To use it, this value then set the copy's state
   member to an opened-for-write (FILE*) handle. By default it will
   use stdout.





*/
FSL_EXPORT const fsl_outputer fsl_outputer_FILE;

/**
   fsl_outputer initializer which uses fsl_flush_f_FILE(),
   fsl_output_f_FILE(), and fsl_finalizer_f_FILE().
*/
#define fsl_outputer_FILE_m {                   \
    fsl_output_f_FILE,                          \
    fsl_flush_f_FILE,                         \

    NULL \


  }
/**
   Generic stateful alloc/free/realloc() interface.

   Implementations must behave as follows:

   - If 0==n then semantically behave like free(3) and return
Changes to src/annotate.c.
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
                                 fsl_annotate_opt const * const opt,
                                 fsl_annotate_step const * const step){
  fsl_outputer const * fout = (fsl_outputer*)state;

  static const int szHash = 10;
  int rc = 0;
  if(opt->dumpVersions && !step->line){
    rc = fsl_appendf(fout->out, fout->state.state,
                     "version %3" PRIu32 ": %s %.*s file %.*s\n",
                     step->stepNumber, step->ymd, szHash,
                     step->versionHash, szHash, step->fileHash);
  }else if(opt->praise){
    if(step->ymd){
      rc = fsl_appendf(fout->out, fout->state.state,
                       "%.*s %s %13.13s: %.*s\n",
                       szHash,
                       opt->fileVersions ? step->fileHash : step->versionHash,
                       step->ymd, step->username,
                       (int)step->lineLength, step->line);
    }else{
      rc = fsl_appendf(fout->out, fout->state.state,
                       "%*s %.*s\n", szHash+26, "",
                       (int)step->lineLength, step->line);
    }
  }else{
    if(step->ymd){
      rc = fsl_appendf(fout->out, fout->state.state,
                     "%.*s %s %5" PRIu32 ": %.*s\n",
                     szHash, opt->fileVersions ? step->fileHash : step->versionHash,
                     step->ymd, step->lineNumber,
                       (int)step->lineLength, step->line);
    }else{
      rc = fsl_appendf(fout->out, fout->state.state,
                       "%*s %5" PRIu32 ": %.*s\n",
                       szHash+11, "", step->lineNumber,
                       (int)step->lineLength, step->line);
    }
  }
  return rc;
}







|





|






|





|





|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
                                 fsl_annotate_opt const * const opt,
                                 fsl_annotate_step const * const step){
  fsl_outputer const * fout = (fsl_outputer*)state;

  static const int szHash = 10;
  int rc = 0;
  if(opt->dumpVersions && !step->line){
    rc = fsl_appendf(fout->out, fout->state,
                     "version %3" PRIu32 ": %s %.*s file %.*s\n",
                     step->stepNumber, step->ymd, szHash,
                     step->versionHash, szHash, step->fileHash);
  }else if(opt->praise){
    if(step->ymd){
      rc = fsl_appendf(fout->out, fout->state,
                       "%.*s %s %13.13s: %.*s\n",
                       szHash,
                       opt->fileVersions ? step->fileHash : step->versionHash,
                       step->ymd, step->username,
                       (int)step->lineLength, step->line);
    }else{
      rc = fsl_appendf(fout->out, fout->state,
                       "%*s %.*s\n", szHash+26, "",
                       (int)step->lineLength, step->line);
    }
  }else{
    if(step->ymd){
      rc = fsl_appendf(fout->out, fout->state,
                     "%.*s %s %5" PRIu32 ": %.*s\n",
                     szHash, opt->fileVersions ? step->fileHash : step->versionHash,
                     step->ymd, step->lineNumber,
                       (int)step->lineLength, step->line);
    }else{
      rc = fsl_appendf(fout->out, fout->state,
                       "%*s %5" PRIu32 ": %.*s\n",
                       szHash+11, "", step->lineNumber,
                       (int)step->lineLength, step->line);
    }
  }
  return rc;
}
Changes to src/cli.c.
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
  init.config.sqlPrint = 1;
  if(fcli.config.outputer.out){
    init.output = fcli.config.outputer;
    fcli.config.outputer = fsl_outputer_empty
      /* To avoid any confusion about ownership */;
  }else{
    init.output = fsl_outputer_FILE;
    init.output.state.state = stdout;
  }
  if(fcli.config.traceSql>0 || TempFlags.traceSql){
    init.config.traceSql = fcli.config.traceSql;
  }
    
  rc = fsl_cx_init( &f, &init );
  fcli.f = f;







|







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
  init.config.sqlPrint = 1;
  if(fcli.config.outputer.out){
    init.output = fcli.config.outputer;
    fcli.config.outputer = fsl_outputer_empty
      /* To avoid any confusion about ownership */;
  }else{
    init.output = fsl_outputer_FILE;
    init.output.state = stdout;
  }
  if(fcli.config.traceSql>0 || TempFlags.traceSql){
    init.config.traceSql = fcli.config.traceSql;
  }
    
  rc = fsl_cx_init( &f, &init );
  fcli.f = f;
Changes to src/cx.c.
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
int fsl_cx_init( fsl_cx ** tgt, fsl_cx_init_opt const * param ){
  static fsl_cx_init_opt paramDefaults = fsl_cx_init_opt_default_m;
  int rc = 0;
  fsl_cx * f;
  extern int fsl_cx_install_timeline_crosslinkers(fsl_cx *f);
  if(!tgt) return FSL_RC_MISUSE;
  else if(!param){
    if(!paramDefaults.output.state.state){
      paramDefaults.output.state.state = stdout;
    }
    param = &paramDefaults;
  }
  if(*tgt){
    void const * allocStamp = (*tgt)->allocStamp;
    fsl_cx_reset(*tgt, 1) /* just to be safe */;
    f = *tgt;







|
|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
int fsl_cx_init( fsl_cx ** tgt, fsl_cx_init_opt const * param ){
  static fsl_cx_init_opt paramDefaults = fsl_cx_init_opt_default_m;
  int rc = 0;
  fsl_cx * f;
  extern int fsl_cx_install_timeline_crosslinkers(fsl_cx *f);
  if(!tgt) return FSL_RC_MISUSE;
  else if(!param){
    if(!paramDefaults.output.state){
      paramDefaults.output.state = stdout;
    }
    param = &paramDefaults;
  }
  if(*tgt){
    void const * allocStamp = (*tgt)->allocStamp;
    fsl_cx_reset(*tgt, 1) /* just to be safe */;
    f = *tgt;
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
}

void fsl_cx_finalize( fsl_cx * f ){
  void const * allocStamp = f ? f->allocStamp : NULL;
  if(!f) return;

  if(f->xlinkers.list){
#if 0
    /* Potential TODO: add client-specified finalizer for xlink
       callback state, using a fsl_state to replace the current
       (void*) for x->state. Seems like overkill for the time being.
     */
    fsl_size_t i;
    for( i = 0; i < f->xlinkers.used; ++i ){
      fsl_xlinker * x = f->xlinkers.list + i;
      if(x->state.finalize.f){
        x->state.finalize.f(x->state.finalize.state, x->state.state);
      }
    }
#endif    
    fsl_free(f->xlinkers.list);
    f->xlinkers = fsl_xlinker_list_empty;
  }

  if(f->clientState.finalize.f){
    f->clientState.finalize.f( f->clientState.finalize.state,
                               f->clientState.state );
  }
  f->clientState = fsl_state_empty;
  if(f->output.state.finalize.f){
    f->output.state.finalize.f( f->output.state.finalize.state,
                                f->output.state.state );
  }
  f->output = fsl_outputer_empty;
  fsl_cx_reset(f, 1);
  fsl_db_close(&f->dbMem);
  *f = fsl_cx_empty;
  if(&fsl_cx_empty == allocStamp){
    fsl_free(f);
  }else{







<
<
<
<
<
<
<
<
<
<
<
<
<









<
<
<
<







210
211
212
213
214
215
216













217
218
219
220
221
222
223
224
225




226
227
228
229
230
231
232
}

void fsl_cx_finalize( fsl_cx * f ){
  void const * allocStamp = f ? f->allocStamp : NULL;
  if(!f) return;

  if(f->xlinkers.list){













    fsl_free(f->xlinkers.list);
    f->xlinkers = fsl_xlinker_list_empty;
  }

  if(f->clientState.finalize.f){
    f->clientState.finalize.f( f->clientState.finalize.state,
                               f->clientState.state );
  }
  f->clientState = fsl_state_empty;




  f->output = fsl_outputer_empty;
  fsl_cx_reset(f, 1);
  fsl_db_close(&f->dbMem);
  *f = fsl_cx_empty;
  if(&fsl_cx_empty == allocStamp){
    fsl_free(f);
  }else{
Changes to src/io.c.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    return rc;
  }
}

int fsl_output( fsl_cx * cx, void const * src, fsl_size_t n ){
  if(!cx || !src) return FSL_RC_MISUSE;
  else if(!n || !cx->output.out) return 0;
  else return cx->output.out( cx->output.state.state,
                              src, n );
}

int fsl_flush( fsl_cx * f ){
  return f
    ? (f->output.flush
       ? f->output.flush(f->output.state.state)
       : 0)
    : FSL_RC_MISUSE;
}


int fsl_flush_f_FILE(void * _FILE){
  return _FILE







|
<





|







53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
    return rc;
  }
}

int fsl_output( fsl_cx * cx, void const * src, fsl_size_t n ){
  if(!cx || !src) return FSL_RC_MISUSE;
  else if(!n || !cx->output.out) return 0;
  else return cx->output.out( cx->output.state, src, n );

}

int fsl_flush( fsl_cx * f ){
  return f
    ? (f->output.flush
       ? f->output.flush(f->output.state)
       : 0)
    : FSL_RC_MISUSE;
}


int fsl_flush_f_FILE(void * _FILE){
  return _FILE