summaryrefslogtreecommitdiff
path: root/gnu/lib/libf2c/libF77/s_cat.c
blob: 4e8da1b3fdb02956791fc68407ab9473eebf277a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/* Unless compiled with -DNO_OVERWRITE, this variant of s_cat allows the
 * target of a concatenation to appear on its right-hand side (contrary
 * to the Fortran 77 Standard, but in accordance with Fortran 90).
 */

#include "f2c.h"
#ifndef NO_OVERWRITE
#include <stdio.h>
#undef abs
#undef min
#undef max
#include <stdlib.h>
extern char *F77_aloc (ftnlen, char *);
#include <string.h>
#endif /* NO_OVERWRITE */

void
s_cat (char *lp, char *rpp[], ftnint rnp[], ftnint * np, ftnlen ll)
{
  ftnlen i, nc;
  char *rp;
  ftnlen n = *np;
#ifndef NO_OVERWRITE
  ftnlen L, m;
  char *lp0, *lp1;

  lp0 = 0;
  lp1 = lp;
  L = ll;
  i = 0;
  while (i < n)
    {
      rp = rpp[i];
      m = rnp[i++];
      if (rp >= lp1 || rp + m <= lp)
	{
	  if ((L -= m) <= 0)
	    {
	      n = i;
	      break;
	    }
	  lp1 += m;
	  continue;
	}
      lp0 = lp;
      lp = lp1 = F77_aloc (L = ll, "s_cat");
      break;
    }
  lp1 = lp;
#endif /* NO_OVERWRITE */
  for (i = 0; i < n; ++i)
    {
      nc = ll;
      if (rnp[i] < nc)
	nc = rnp[i];
      ll -= nc;
      rp = rpp[i];
      while (--nc >= 0)
	*lp++ = *rp++;
    }
  while (--ll >= 0)
    *lp++ = ' ';
#ifndef NO_OVERWRITE
  if (lp0)
    {
      memcpy (lp0, lp1, L);
      free (lp1);
    }
#endif
}