Fix NSRange bits for range_t.
Add includes for logging.hh
Rewrite doc comment for s_fatal_error_impl.
Updates to ref_counter_t

* Removed default finalizer.
* release now returns a boolean value, indicating whether or not the
  object was/should be released.
* finalizer functions are now optional.
* ref_counter_t::clear() added to wipe out any retain counts already
  tracked.
Add logging prefixes for s_log_* macros.

Can be overridden if needed.
Prevent premake4.lua from regen'ing files when nothing is done.
Add string/* includes to config.hh
Tweaks to string handling.

- Now banned: use of std::string::length().
Add snow::string_t

This class is basically the new Snow string class. It's not 100%
compatible with std::string and has a lot of find functions. The goal
here is mainly to make the buffer behind the string accessible (so you
can into it from a stream without creating a new string).

It's almost guaranteed _not_ to be as fast as good as std::string for
most purposes, but it's easier to debug than std::string and allows for
some things I needed in the Snow engine.

A few notable differences between this and std::string:

- No length() function. This is an oddity in std::string and I don't
  see a reason to add it if it's just a synonym for size().

- find() returns iterators, _not_ indices. If you want indices, use
  find_index(). These both mostly conform to the same interface as
  std::string::find, but can optionally take iterators to specify a
  'from' position to begin the find. finding a substring does allocate
  a temporary vector to build the table needed for KMP, but it's not a
  huge issue and may later be replaced with dynarray or alloca calls
  in some cases. However, find() performance isn't a problem at runtime
  so I'm not too concerned with it.

- string_t() can be constructed with pointers that it will not free.
  These can act either as windows into substrings (see window()) or
  just as string wrappers for other data. There is still the penalty
  of allocating a string object, which is about 24 bytes on 64-bit
  systems (likely 16-ish on 32-bit), but it's probably not significant.

- Comparing a string with a C-string will not allocate a new string_t,
  however, and chances are this won't be a bottleneck. Profiling still
  needs to be done to determine where string_t needs improvement anyway,
  so there's not going to be a lot of time spent on that until there's
  enough going on to get some useful data on performance.

- There are a lot of other methods missing, like insert(), which is on
  the to-do list but probably won't get put in until I actually need it.

- No reverse-find functions. Period. these won't be added.

- It has both has_prefix and has_suffix functions. These are mostly for
  convenience.

- No replace, copy, or swap functions. These probably won't be added
  because you've already got std::swap, replace hasn't come up as a
  function I need yet, and copy doesn't need to exist.

- No max_size function because it's not actually useful.

- Allocators are not yet supported. I'm not particularly happy about
  this, but it's on the to-do list.

- Also, it's not templated like std::basic_string, of course. You shall
  not use non-UTF-8 strings. Period.

- Probably some other things I don't notice right now.
Change string internals a bit

Now uses as much of the length and capacity variables as it can. This
should allow it to avoid additional allocations for shorter strings.
Downside is that it does make the code slightly more complicated, but
not as much as I thought it would. Did have to resort to a sort of hack
to get a fixed size for the short data array, though.
Check for trailing \n and remmove it from log messages
Add a log callback function.

This is mainly used to write log messages to the console in-engine.
It's not thread-safe or particularly flexible, but it works.