Let a B-spline of degree $p$ be defined by its parametric equation $$ \mathbf{r}(t) = \sum_{i=0}^n N_i^p(t)\mathbf{P}_i$$
where the $n+1$ control points are denoted by $\mathbf{P}_i$. The basis functions $N_i^p$ are classically defined as
$$ \begin{align} N_i^0(t) &= \begin{cases} 1 &\text{ if }t \in [t_i,t_{i+1}[ \\ 0 &\text{ otherwise } \end{cases} \end{align} $$ $$ \begin{align} N_i^p(t) = \frac{t - t_i}{t_{i + p} - t_i}N_i^{p-1} + \frac{t_{i + p + 1} - t}{t_{i + p + 1} - t_{i + 1}}N_{i+1}^{p-1} \end{align} $$ where $\{t_i\}_{i = 0..m = n + p + 1}$ are the so-called spline knots.
It is my understanding that because of the compact support of those basis functions, one only needs to evaluate the parametric equation over $[t_p,t_{m-p}]$ to obtain the full spline.
My current implementation of these equations appears to work when the spline is left open (no knot has a multiplicity equal to p + 1):
For uniformly spaced knots $t = [ 0, 1/6, 1/3, 1/2, 2/3, 5/6, 1 ]$ (m = 6) and a control net comprised of $n + 1 = 4$ points, thus corresponding to a spline of degree $p =2$, I get the following curve (which as I said seems correct)
However, enforcing the clamping of the spline's ends by setting
$ t= [ 0, 0, 0, 0.5, 1, 1, 1 ]$ only works on one end, as shown below
Clamped B-spline. Only one end is clamped properly
The end corresponding to $t_p = 0$ is clamped, but the other end corresponding to $t_{m-p} = 1$ goes to zero.
I believe this oddity is caused by the incorrect definition of the B-spline support in the clamped case. I found that changing $ N_i^0(t) = 1 $ if $ t \in [t_i,t_{i+1}[ $ to $ N_i^0(t) = 1 $ if $ t \in [t_i,t_{i+1}] $ (i.e using a closed interval instead) was allowing the clamping to work.
This being said, I am not sure at all that changing the support of the basis functions is required in order to get a clamped B-spline. Am I missing something?
If one starts from a definition of b(asis)-splines like that one in De Boor's book "A Practical Guide to Splines" basing on divided differences \begin{align*} N_i^p(t) = (t_{i+p+1}-t_i)[t_i,\ldots,t_{i+p+1}]_{\bar t} (\bar t - t)_+^p \end{align*} with \begin{align*} (x)_+^p = \begin{cases} 0 &@\ x\leq 0\\ x^p &@\ x > 0\end{cases} \end{align*} the convention $x^0:=0$ and a given knot sequence $(t_i)_{i=0}^m$ with $t_i\leq t_{i+1}$. Then this leads to right-continuous functions. Note, that your recursive formula works for this definition.
Case $p=0$ and $t_i<t_{i+1}$: \begin{align*} N_i^0(t) &= (t_{i+1}-t_i) [t_i,t_{i+1}]_{\bar t} (\bar t - t)_+^0\\ &=(t_{i+1}-t_i)\frac{(t_{i+1}-t)_+^0 - (t_i - t)_+^0}{t_{i+1}-t_i}\\ &=\begin{cases} 1 &@\ t\in [t_i,t_{i+1}[\\ 0 &@\text{ else} \end{cases} \end{align*}
Last base function for the case $p=1$: \begin{align*} N^1_{n}(t) &= (t_{n+1}-t_n) [t_n,t_{n+1},t_{n+1}]_{\bar t}(\bar t-t)_+\\ &= [t_{n+1},t_{n+1}](\bar t - t)_+ - [t_n,t_{n+1}](\bar t - t)_+\\ &= \left.\frac{d}{d \bar t}(\bar t - t)_+\right|_{\bar t=t_{n+1}} - \frac{(t_{n+1} - t)_+ - (t_n - t)_+}{t_{n+1}-t_n}\\ &= \begin{cases} 0 &@\ t < t_n\\ \displaystyle 1-\frac{(t_{n+1} - t)_+ }{t_{n+1}-t_n}&@\ t_n\leq t < t_{n+1}\\ 0 &@\ t_{n+1}\leq t \end{cases} \end{align*} This base function is discontinuous at $t=t_{n+1}$. The limit from the left is not equal to the value at $t=t_{n+1}$.
In praxis one does not really use the last base function directly but the continuous continuation of it from the half-open interval $[t_p,t_{m-p}[$ to the closed interval $[t_p,t_{m-p}]$.
This is simply done by limiting the search for the index $i$ with $t\in [t_i,t_{i+1}[$ to the largest of the indexes of the inner knots.
Beforehand one should check whether $t$ falls within the interval $[t_p,t_{m-p}]$. Places $t$ outside of this interval often get a special treatment such as linear extrapolation (this is only one of several alternatives to the nulling that the base functions cause there).