summaryrefslogtreecommitdiffstats
path: root/lib/libF77/s_cat.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libF77/s_cat.c')
-rw-r--r--lib/libF77/s_cat.c80
1 files changed, 63 insertions, 17 deletions
diff --git a/lib/libF77/s_cat.c b/lib/libF77/s_cat.c
index 7f55cd5..1d6fd24 100644
--- a/lib/libF77/s_cat.c
+++ b/lib/libF77/s_cat.c
@@ -1,25 +1,71 @@
+/* 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
+#ifdef KR_headers
+ extern char *F77_aloc();
+ extern void free();
+ extern void exit_();
+#else
+#include "stdlib.h"
+ extern char *F77_aloc(ftnlen, char*);
+#endif
+#include "string.h"
+#endif /* NO_OVERWRITE */
+ VOID
#ifdef KR_headers
-VOID s_cat(lp, rpp, rnp, np, ll) char *lp, *rpp[]; ftnlen rnp[], *np, ll;
+s_cat(lp, rpp, rnp, np, ll) char *lp, *rpp[]; ftnlen rnp[], *np, ll;
#else
-VOID s_cat(char *lp, char *rpp[], ftnlen rnp[], ftnlen *np, ftnlen ll)
+s_cat(char *lp, char *rpp[], ftnlen rnp[], ftnlen *np, ftnlen ll)
#endif
{
-ftnlen i, n, nc;
-char *f__rp;
+ ftnlen i, nc;
+ char *rp;
+ ftnlen n = *np;
+#ifndef NO_OVERWRITE
+ ftnlen L, m;
+ char *lp0, *lp1;
-n = *np;
-for(i = 0 ; i < n ; ++i)
- {
- nc = ll;
- if(rnp[i] < nc)
- nc = rnp[i];
- ll -= nc;
- f__rp = rpp[i];
- while(--nc >= 0)
- *lp++ = *f__rp++;
+ 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");
+ }
+#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
}
-while(--ll >= 0)
- *lp++ = ' ';
-}
OpenPOWER on IntegriCloud