Login
Check-in [fdc5e1014e]
Login

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

Overview
Comment:Moved C++ and s2 bindings to bindings/{cpp,s2}. Got the C++ bindings compiling for new gcc breakage and new, stricter T-card validation.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fdc5e1014e2d09fc0f1aa0e45d8c19805b9aa5d8
User & Date: stephan 2021-02-11 12:42:23.114
Context
2021-02-11
12:49
Checked in the generated fsl_schema_*_cstr.c files to make it easier to port the build to non-Unix systems. check-in: eeac3c6fe0 user: stephan tags: trunk
12:42
Moved C++ and s2 bindings to bindings/{cpp,s2}. Got the C++ bindings compiling for new gcc breakage and new, stricter T-card validation. check-in: fdc5e1014e user: stephan tags: trunk
12:25
Moved f-tools wiki page to f-apps/index.md. check-in: 827f5c8bc3 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to auto.def.
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
    define DOXYGEN_HAVE_DOT YES
    msg-result "Adding HAVE_DOT=YES to doxyfile."
} else {
    define DOXYGEN_HAVE_DOT NO
}


# Creates mkefile(-like) file $name from $name.in

proc makeFromDotIn {name} {
    catch { exec chmod u+w $name }
    make-template $name.in $name
    catch { exec chmod u-w $name }
}
# Each generated Makefile requires an input file with a .in extension:
set makefiles {
    config.make
    Makefile
    doc/Doxyfile
    src/Makefile
    f-apps/Makefile
    cpp/Makefile
}
foreach {f} $makefiles {
    makeFromDotIn $f
}

if {0} {
    # Achtung: ordering of the -bare/-str options here is important







|
>












|







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
388
    define DOXYGEN_HAVE_DOT YES
    msg-result "Adding HAVE_DOT=YES to doxyfile."
} else {
    define DOXYGEN_HAVE_DOT NO
}


# Creates mkefile(-like) file $name from $name.in but explicitly makes
# the output read-only, to avoid inadvertent editing (who, me?).
proc makeFromDotIn {name} {
    catch { exec chmod u+w $name }
    make-template $name.in $name
    catch { exec chmod u-w $name }
}
# Each generated Makefile requires an input file with a .in extension:
set makefiles {
    config.make
    Makefile
    doc/Doxyfile
    src/Makefile
    f-apps/Makefile
    bindings/cpp/Makefile
}
foreach {f} $makefiles {
    makeFromDotIn $f
}

if {0} {
    # Achtung: ordering of the -bare/-str options here is important
Name change from cpp/Context.cpp to bindings/cpp/Context.cpp.
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  std::string Context::ridToArtifactUuid(fsl_id_t rid,
                                         fsl_catype_t type){
    this->assertHasRepo();
    fsl_uuid_str uuid = fsl_rid_to_artifact_uuid(*this, rid, type);
    if(!uuid){
      this->propagateError();
      throw Exception(FSL_RC_NOT_FOUND,
                      "Could not resolve RID %"FSL_ID_T_PFMT
                      " as artifact type %s.",
                      (fsl_id_t)rid, fsl_catype_cstr(type));
    }
    std::string const & rc = uuid;
    fsl_free(uuid);
    return rc;
  }

  std::string Context::ridToUuid(fsl_id_t rid){
    this->assertHasRepo();
    fsl_uuid_str uuid = fsl_rid_to_uuid(*this, rid);
    if(!uuid){
      this->propagateError();
      throw Exception(FSL_RC_NOT_FOUND, "Could not resolve RID %"FSL_ID_T_PFMT".",
                      (fsl_id_t)rid);
    }
    std::string const & rc = uuid;
    fsl_free(uuid);
    return rc;
  }








|













|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  std::string Context::ridToArtifactUuid(fsl_id_t rid,
                                         fsl_catype_t type){
    this->assertHasRepo();
    fsl_uuid_str uuid = fsl_rid_to_artifact_uuid(*this, rid, type);
    if(!uuid){
      this->propagateError();
      throw Exception(FSL_RC_NOT_FOUND,
                      "Could not resolve RID %" FSL_ID_T_PFMT
                      " as artifact type %s.",
                      (fsl_id_t)rid, fsl_catype_cstr(type));
    }
    std::string const & rc = uuid;
    fsl_free(uuid);
    return rc;
  }

  std::string Context::ridToUuid(fsl_id_t rid){
    this->assertHasRepo();
    fsl_uuid_str uuid = fsl_rid_to_uuid(*this, rid);
    if(!uuid){
      this->propagateError();
      throw Exception(FSL_RC_NOT_FOUND, "Could not resolve RID %" FSL_ID_T_PFMT ".",
                      (fsl_id_t)rid);
    }
    std::string const & rc = uuid;
    fsl_free(uuid);
    return rc;
  }

Name change from cpp/Db.cpp to bindings/cpp/Db.cpp.
Name change from cpp/Deck.cpp to bindings/cpp/Deck.cpp.
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  Deck & Deck::load( fsl_id_t rid, fsl_catype_t type ){
    this->cleanup();
    int const rc = fsl_deck_load_rid( this->cx, *this,
                                      rid, type );
    if(rc){
      this->propagateError();
      throw Exception(rc, "fsl_deck_load_rid() failed "
                      "with %s for symbol: %"FSL_ID_T_PFMT,
                      fsl_rc_cstr(rc), (fsl_id_t)rid);
    }else return *this;
  }

  Deck & Deck::load( char const * symbolicName, fsl_catype_t type){
    this->cleanup();
    int const rc = fsl_deck_load_sym( this->cx, *this,







|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  Deck & Deck::load( fsl_id_t rid, fsl_catype_t type ){
    this->cleanup();
    int const rc = fsl_deck_load_rid( this->cx, *this,
                                      rid, type );
    if(rc){
      this->propagateError();
      throw Exception(rc, "fsl_deck_load_rid() failed "
                      "with %s for symbol: %" FSL_ID_T_PFMT,
                      fsl_rc_cstr(rc), (fsl_id_t)rid);
    }else return *this;
  }

  Deck & Deck::load( char const * symbolicName, fsl_catype_t type){
    this->cleanup();
    int const rc = fsl_deck_load_sym( this->cx, *this,
Name change from cpp/Exception.cpp to bindings/cpp/Exception.cpp.
Name change from cpp/Fossil.cpp to bindings/cpp/Fossil.cpp.
Name change from cpp/Makefile.in to bindings/cpp/Makefile.in.
1
2
3
4
5
6
7
8
9
all:
include ../subdir-inc.make
#$(error $(TOP_SRCDIR))
#CPPFLAGS += -I$(TOP_INCDIR)
#CPPFLAGS += -I$(TOP_SRCDIR)/include
CPPFLAGS += -I$(TOP_SRCDIR)/src# workaround for in-tree sqlite3.h
CXXFLAGS += -fPIC -Wall -Werror

#INCLUDES_PATH ?= $(HOME)/include /usr/local/include /usr/include

|







1
2
3
4
5
6
7
8
9
all:
include ../../subdir-inc.make
#$(error $(TOP_SRCDIR))
#CPPFLAGS += -I$(TOP_INCDIR)
#CPPFLAGS += -I$(TOP_SRCDIR)/include
CPPFLAGS += -I$(TOP_SRCDIR)/src# workaround for in-tree sqlite3.h
CXXFLAGS += -fPIC -Wall -Werror

#INCLUDES_PATH ?= $(HOME)/include /usr/local/include /usr/include
Name change from cpp/OStream.cpp to bindings/cpp/OStream.cpp.
Name change from cpp/test.cpp to bindings/cpp/test.cpp.
163
164
165
166
167
168
169



170
171
172
173
174
175
176
177
178
179
180
181
182
  }
  assert(FSL_RC_CA_SYNTAX==threw);

  {
    f::Context::Transaction tr(cx)
      /* We'll roll back everything done here... */
      ;



    fout << "Custom "<< fsl_catype_cstr(d.type()) << " deck:\n";
    d.setCardD()
      .setCardU()
      .addCardT(FSL_TAGTYPE_ADD, "myTag", NULL, "its value")
      .addCardT(FSL_TAGTYPE_PROPAGATING, "myOtherTag")
      .addCardT(FSL_TAGTYPE_CANCEL, "sumdumtag")
      //.unshuffle().output(fout)
      ;
    d.save();
    fout << "RID/UUID after save (will be rolled back): "<<d.rid() << ' ' << d.uuid()<<'\n';


    {







>
>
>



|
|
|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  }
  assert(FSL_RC_CA_SYNTAX==threw);

  {
    f::Context::Transaction tr(cx)
      /* We'll roll back everything done here... */
      ;
    const char * tgtArty = "99237c3636730f20ed07b227c5092c087aea8b0c"
      /* self-referencing tag in a FSL_CATYPE_CONTROL is not legal, so
         we arbitrarily choose the initial empty checking. */;
    fout << "Custom "<< fsl_catype_cstr(d.type()) << " deck:\n";
    d.setCardD()
      .setCardU()
      .addCardT(FSL_TAGTYPE_ADD, "myTag", tgtArty, "its value")
      .addCardT(FSL_TAGTYPE_PROPAGATING, "myOtherTag", tgtArty)
      .addCardT(FSL_TAGTYPE_CANCEL, "sumdumtag", tgtArty)
      //.unshuffle().output(fout)
      ;
    d.save();
    fout << "RID/UUID after save (will be rolled back): "<<d.rid() << ' ' << d.uuid()<<'\n';


    {
Name change from s2/Makefile to bindings/s2/Makefile.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
all:
include ../subdir-inc.make

CPPFLAGS += -I$(TOP_SRCDIR)/src# workaround for in-tree sqlite3.h
CPPFLAGS += -fPIC
CPPFLAGS+=-DCWAL_ENABLE_TRACE=0

LIBFOSSIL.LDFLAGS := -L.. -lfossil
ifeq (1,1)
  # In static build, we need some extra flags...
  LIBFOSSIL.LDFLAGS += $(LDFLAGS_MODULE_LOADER) -lpthread -lz
endif

ifeq (,$(strip $(filter distclean clean,$(MAKECMDGOALS))))
$(LIBFOSSIL.LDFLAGS):

|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
all:
include ../../subdir-inc.make

CPPFLAGS += -I$(TOP_SRCDIR)/src# workaround for in-tree sqlite3.h
CPPFLAGS += -fPIC
CPPFLAGS+=-DCWAL_ENABLE_TRACE=0

LIBFOSSIL.LDFLAGS := -L$(TOP_SRCDIR) -lfossil
ifeq (1,1)
  # In static build, we need some extra flags...
  LIBFOSSIL.LDFLAGS += $(LDFLAGS_MODULE_LOADER) -lpthread -lz
endif

ifeq (,$(strip $(filter distclean clean,$(MAKECMDGOALS))))
$(LIBFOSSIL.LDFLAGS):
Name change from s2/cliapp.c to bindings/s2/cliapp.c.
Name change from s2/cliapp.h to bindings/s2/cliapp.h.
Name change from s2/config.h to bindings/s2/config.h.
Name change from s2/f-s2sh.s2 to bindings/s2/f-s2sh.s2.
Name change from s2/fslcgi to bindings/s2/fslcgi.
Name change from s2/fslcgi.d/init.s2 to bindings/s2/fslcgi.d/init.s2.
Name change from s2/fslcgi.s2 to bindings/s2/fslcgi.s2.
Name change from s2/linenoise/linenoise.c to bindings/s2/linenoise/linenoise.c.
Name change from s2/linenoise/linenoise.h to bindings/s2/linenoise/linenoise.h.
Name change from s2/linenoise/utf8.c to bindings/s2/linenoise/utf8.c.
Name change from s2/linenoise/utf8.h to bindings/s2/linenoise/utf8.h.
Name change from s2/r-tester.sh to bindings/s2/r-tester.sh.
Name change from s2/require-demo.s2 to bindings/s2/require-demo.s2.
Name change from s2/require.d/BufferFactory.s2 to bindings/s2/require.d/BufferFactory.s2.
Name change from s2/require.d/BufferFactory.test.s2 to bindings/s2/require.d/BufferFactory.test.s2.
Name change from s2/require.d/DataModels/TestModel.s2 to bindings/s2/require.d/DataModels/TestModel.s2.
Name change from s2/require.d/Ticker.s2 to bindings/s2/require.d/Ticker.s2.
Name change from s2/require.d/Ticker.test.s2 to bindings/s2/require.d/Ticker.test.s2.
Name change from s2/require.d/cliargs.s2 to bindings/s2/require.d/cliargs.s2.
Name change from s2/require.d/fsl/context.s2 to bindings/s2/require.d/fsl/context.s2.
Name change from s2/require.d/fsl/db/checkout.s2 to bindings/s2/require.d/fsl/db/checkout.s2.
Name change from s2/require.d/fsl/db/config.s2 to bindings/s2/require.d/fsl/db/config.s2.
Name change from s2/require.d/fsl/db/main.s2 to bindings/s2/require.d/fsl/db/main.s2.
Name change from s2/require.d/fsl/db/repo.s2 to bindings/s2/require.d/fsl/db/repo.s2.
Name change from s2/require.d/fsl/db/repoOrCheckout.s2 to bindings/s2/require.d/fsl/db/repoOrCheckout.s2.
Name change from s2/require.d/fsl/extendFossil.s2 to bindings/s2/require.d/fsl/extendFossil.s2.
Name change from s2/require.d/fsl/reports/common.s2 to bindings/s2/require.d/fsl/reports/common.s2.
Name change from s2/require.d/fsl/reports/common.test.s2 to bindings/s2/require.d/fsl/reports/common.test.s2.
Name change from s2/require.d/fsl/timeline/basic.s2 to bindings/s2/require.d/fsl/timeline/basic.s2.
Name change from s2/require.d/fsl/util/repo.s2 to bindings/s2/require.d/fsl/util/repo.s2.
Name change from s2/require.d/fsl/util/repo.test.s2 to bindings/s2/require.d/fsl/util/repo.test.s2.
Name change from s2/require.d/fsl/wiki/pageNames.s2 to bindings/s2/require.d/fsl/wiki/pageNames.s2.
Name change from s2/require.d/fsl/wiki/util.s2 to bindings/s2/require.d/fsl/wiki/util.s2.
Name change from s2/require.d/io.s2 to bindings/s2/require.d/io.s2.
Name change from s2/require.d/json.s2 to bindings/s2/require.d/json.s2.
Name change from s2/require.d/json2.s2 to bindings/s2/require.d/json2.s2.
Name change from s2/require.d/json2.test.s2 to bindings/s2/require.d/json2.test.s2.
Name change from s2/require.d/ob.s2 to bindings/s2/require.d/ob.s2.
Name change from s2/require.d/ostream.s2 to bindings/s2/require.d/ostream.s2.
Name change from s2/require.d/plugins/demo.s2 to bindings/s2/require.d/plugins/demo.s2.
Name change from s2/require.d/plugins/dll.s2 to bindings/s2/require.d/plugins/dll.s2.
Name change from s2/require.d/plugins/fsl/blob.s2 to bindings/s2/require.d/plugins/fsl/blob.s2.
Name change from s2/require.d/plugins/fsl/manifest.s2 to bindings/s2/require.d/plugins/fsl/manifest.s2.
Name change from s2/require.d/plugins/fsl/wikiByName.s2 to bindings/s2/require.d/plugins/fsl/wikiByName.s2.
Name change from s2/require.d/plugins/json-cached.s2 to bindings/s2/require.d/plugins/json-cached.s2.
Name change from s2/require.d/plugins/json.s2 to bindings/s2/require.d/plugins/json.s2.
Name change from s2/require.d/plugins/placeholder.s2 to bindings/s2/require.d/plugins/placeholder.s2.
Name change from s2/require.d/plugins/tmpl-compiled.s2 to bindings/s2/require.d/plugins/tmpl-compiled.s2.
Name change from s2/require.d/plugins/tmpl.s2 to bindings/s2/require.d/plugins/tmpl.s2.
Name change from s2/require.d/pubsub.s2 to bindings/s2/require.d/pubsub.s2.
Name change from s2/require.d/pubsub.test.s2 to bindings/s2/require.d/pubsub.test.s2.
Name change from s2/require.d/require.s2 to bindings/s2/require.d/require.s2.
Name change from s2/require.d/require.test.s2 to bindings/s2/require.d/require.test.s2.
Name change from s2/require.d/time.s2 to bindings/s2/require.d/time.s2.
Name change from s2/require.d/tmpl.s2 to bindings/s2/require.d/tmpl.s2.
Name change from s2/require.d/tmpl.test.s2 to bindings/s2/require.d/tmpl.test.s2.
Name change from s2/s2_amalgamation.c to bindings/s2/s2_amalgamation.c.
Name change from s2/s2_amalgamation.h to bindings/s2/s2_amalgamation.h.
Name change from s2/shell.c to bindings/s2/shell.c.
Name change from s2/shell_common.c to bindings/s2/shell_common.c.
Name change from s2/shell_extend.c to bindings/s2/shell_extend.c.
Name change from s2/timeline.s2 to bindings/s2/timeline.s2.
Name change from s2/unit/000-000-0empty.s2 to bindings/s2/unit/000-000-0empty.s2.
Name change from s2/unit/000-000-abc.s2 to bindings/s2/unit/000-000-abc.s2.
Name change from s2/unit/000-005-bitshift.s2 to bindings/s2/unit/000-005-bitshift.s2.
Name change from s2/unit/000-010-compare.s2 to bindings/s2/unit/000-010-compare.s2.
Name change from s2/unit/001-010-typename.s2 to bindings/s2/unit/001-010-typename.s2.
Name change from s2/unit/001-011-nameof.s2 to bindings/s2/unit/001-011-nameof.s2.
Name change from s2/unit/002-000-eval.s2 to bindings/s2/unit/002-000-eval.s2.
Name change from s2/unit/002-050-catch.s2 to bindings/s2/unit/002-050-catch.s2.
Name change from s2/unit/003-000-string-ops.s2 to bindings/s2/unit/003-000-string-ops.s2.
Name change from s2/unit/005-000-var-decl.s2 to bindings/s2/unit/005-000-var-decl.s2.
Name change from s2/unit/010-000-assign.s2 to bindings/s2/unit/010-000-assign.s2.
Name change from s2/unit/010-010-properties.s2 to bindings/s2/unit/010-010-properties.s2.
Name change from s2/unit/010-050-incrdecr.s2 to bindings/s2/unit/010-050-incrdecr.s2.
Name change from s2/unit/015-000-interceptors.s2 to bindings/s2/unit/015-000-interceptors.s2.
Name change from s2/unit/020-000-strings.s2 to bindings/s2/unit/020-000-strings.s2.
Name change from s2/unit/020-050-buffer.s2 to bindings/s2/unit/020-050-buffer.s2.
Name change from s2/unit/030-000-arrays.s2 to bindings/s2/unit/030-000-arrays.s2.
Name change from s2/unit/040-000-objects.s2 to bindings/s2/unit/040-000-objects.s2.
Name change from s2/unit/050-000-func-call.s2 to bindings/s2/unit/050-000-func-call.s2.
Name change from s2/unit/060-000-numbers.s2 to bindings/s2/unit/060-000-numbers.s2.
Name change from s2/unit/070-000-enum.s2 to bindings/s2/unit/070-000-enum.s2.
Name change from s2/unit/099-000-typeinfo.s2 to bindings/s2/unit/099-000-typeinfo.s2.
Name change from s2/unit/100-000-object-methods.s2 to bindings/s2/unit/100-000-object-methods.s2.
Name change from s2/unit/100-050-overloading.s2 to bindings/s2/unit/100-050-overloading.s2.
Name change from s2/unit/200-000-ifelse.s2 to bindings/s2/unit/200-000-ifelse.s2.
Name change from s2/unit/200-100-while.s2 to bindings/s2/unit/200-100-while.s2.
Name change from s2/unit/200-200-for.s2 to bindings/s2/unit/200-200-for.s2.
Name change from s2/unit/200-300-dowhile.s2 to bindings/s2/unit/200-300-dowhile.s2.
Name change from s2/unit/300-000-functions.s2 to bindings/s2/unit/300-000-functions.s2.
Name change from s2/unit/400-000-new.s2 to bindings/s2/unit/400-000-new.s2.
Name change from s2/unit/500-000-array.s2 to bindings/s2/unit/500-000-array.s2.
Name change from s2/unit/600-000-hash.s2 to bindings/s2/unit/600-000-hash.s2.
Name change from s2/unit/650-000-tuple.s2 to bindings/s2/unit/650-000-tuple.s2.
Name change from s2/unit/700-000-foreach.s2 to bindings/s2/unit/700-000-foreach.s2.
Name change from s2/unit/800-000-exception.s2 to bindings/s2/unit/800-000-exception.s2.
Name change from s2/unit/825-000-define.s2 to bindings/s2/unit/825-000-define.s2.
Name change from s2/unit/850-000-pragma.s2 to bindings/s2/unit/850-000-pragma.s2.
Name change from s2/unit/900-000-pathfinder.s2 to bindings/s2/unit/900-000-pathfinder.s2.
Name change from s2/unit/900-001-ob.s2 to bindings/s2/unit/900-001-ob.s2.
Name change from s2/unit/900-002-switch.s2 to bindings/s2/unit/900-002-switch.s2.
Name change from s2/unit/900-003-fs.s2 to bindings/s2/unit/900-003-fs.s2.
Name change from s2/unit/900-004-glob.s2 to bindings/s2/unit/900-004-glob.s2.
Name change from s2/unit/910-000-s2sh.s2 to bindings/s2/unit/910-000-s2sh.s2.
Name change from s2/unit/950-000-bughunt.s2 to bindings/s2/unit/950-000-bughunt.s2.
Name change from s2/unit/Makefile to bindings/s2/unit/Makefile.
Name change from s2/unit2/000-000-sanity.s2 to bindings/s2/unit2/000-000-sanity.s2.
Name change from s2/unit2/000-075-time.s2 to bindings/s2/unit2/000-075-time.s2.
Name change from s2/unit2/000-100-db.s2 to bindings/s2/unit2/000-100-db.s2.
Name change from s2/unit2/000-200-context.s2 to bindings/s2/unit2/000-200-context.s2.
Name change from s2/unit2/100-000-vtbl-settingsmetadata.s2 to bindings/s2/unit2/100-000-vtbl-settingsmetadata.s2.
Name change from s2/unit2/100-100-vtbl-versionedsettings.s2 to bindings/s2/unit2/100-100-vtbl-versionedsettings.s2.
Name change from s2/unit2/Makefile to bindings/s2/unit2/Makefile.
Name change from s2/vg.make to bindings/s2/vg.make.
Changes to f-apps/index.md.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

These applications provide demonstrations of using the library and give devs a place to test new features. `[FossilApp|fcli]` provides a mini-framework which takes care of bootstrapping fossil for these applications, making it pretty simple to create new ones. fcli handles the CLI parsing, global flags, opening of a repo/checkout, and other "getting started" bits. If you've ever hacked on fossil(1), adding a new f-* app is very similar to adding a new command to fossil, with only a few more lines of bootstrap code (because each "command" is in its own app).

## Framework-level TODOs

- Consider (but not too strongly) migrating the "lax" CLI flag
  handling into something more rigid/structured, maybe
  [cliapp.h](/finfo/s2/cliapp.h), primarily so that we can unify the
  help text layout. OTOH, it is very often convenient to have
  free-form help text in these apps, e.g. for injecting examples and
  sidebars along with relevant flag help.

## Demos

```
# f-wiki ls
Timestamp           UUID     Name
2013-08-22@22:26:59 86afdaa5 AmalgamationBuild







|
|
|
|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

These applications provide demonstrations of using the library and give devs a place to test new features. `[FossilApp|fcli]` provides a mini-framework which takes care of bootstrapping fossil for these applications, making it pretty simple to create new ones. fcli handles the CLI parsing, global flags, opening of a repo/checkout, and other "getting started" bits. If you've ever hacked on fossil(1), adding a new f-* app is very similar to adding a new command to fossil, with only a few more lines of bootstrap code (because each "command" is in its own app).

## Framework-level TODOs

- Consider (but not too strongly) migrating the "lax" CLI flag
  handling into something more rigid/structured, maybe
  [cliapp.h](/finfo/bindings/s2/cliapp.h), primarily so that we can
  unify the help text layout. OTOH, it is very often convenient to
  have free-form help text in these apps, e.g. for injecting examples
  and sidebars along with relevant flag help.

## Demos

```
# f-wiki ls
Timestamp           UUID     Name
2013-08-22@22:26:59 86afdaa5 AmalgamationBuild