#define bool int
+#define xstrncpy(d_,s_,l_) \
+ do { \
+ char* dst_=d_; \
+ dst_[0]='\0'; \
+ strncat((dst_),(s_),(l_)-1); \
+ } while(0)
+
typedef void Lang_function __P((FILE *));
typedef struct
static char *skip_non_spaces __P((char *));
static char *savenstr __P((char *, int));
static char *savestr __P((char *));
-static char *etags_strchr __P((const char *, int));
-static char *etags_strrchr __P((const char *, int));
-static int etags_strcasecmp __P((const char *, const char *));
-static int etags_strncasecmp __P((const char *, const char *, int));
static char *etags_getcwd __P((void));
static char *relative_filename __P((char *, char *));
static char *absolute_filename __P((char *, char *));
static PTR xmalloc __P((unsigned int));
static PTR xrealloc __P((char *, unsigned int));
+
+\f
+#if HAVE_STRRCHR
+#define etags_strrchr strrchr
+#else
+/*
+ * Return the ptr in sp at which the character c last
+ * appears; NULL if not found
+ *
+ * Identical to POSIX strrchr, included for portability.
+ */
+static char *
+etags_strrchr (sp, c)
+register const char *sp;
+register int c;
+{
+ register const char *r;
+
+ r = NULL;
+ do
+ {
+ if (*sp == c)
+ r = sp;
+ } while (*sp++);
+ return (char *)r;
+}
+#endif
+
+#if HAVE_STRCHR
+#define etags_strchr strchr
+#else
+/*
+ * Return the ptr in sp at which the character c first
+ * appears; NULL if not found
+ *
+ * Identical to POSIX strchr, included for portability.
+ */
+static char *
+etags_strchr (sp, c)
+register const char *sp;
+register int c;
+{
+ do
+ {
+ if (*sp == c)
+ return (char *)sp;
+ } while (*sp++);
+ return NULL;
+}
+#endif
+
+#if HAVE_STRCASECMP
+#define etags_strcasecmp strcasecmp
+#else
+/*
+ * Compare two strings, ignoring case for alphabetic characters.
+ *
+ * Same as BSD's strcasecmp, included for portability.
+ */
+static int
+etags_strcasecmp (s1, s2)
+register const char *s1;
+register const char *s2;
+{
+ while (*s1 != '\0'
+ && (ISALPHA (*s1) && ISALPHA (*s2)
+ ? lowcase (*s1) == lowcase (*s2)
+ : *s1 == *s2))
+ s1++, s2++;
+
+ return (ISALPHA (*s1) && ISALPHA (*s2)
+ ? lowcase (*s1) - lowcase (*s2)
+ : *s1 - *s2);
+}
+#endif
+
+#if HAVE_STRCASECMP
+#define etags_strncasecmp strncasecmp
+#else
+/*
+ * Compare two strings, ignoring case for alphabetic characters.
+ * Stop after a given number of characters
+ *
+ * Same as BSD's strncasecmp, included for portability.
+ */
+static int
+etags_strncasecmp (s1, s2, n)
+register const char *s1;
+register const char *s2;
+register int n;
+{
+ while (*s1 != '\0' && n-- > 0
+ && (ISALPHA (*s1) && ISALPHA (*s2)
+ ? lowcase (*s1) == lowcase (*s2)
+ : *s1 == *s2))
+ s1++, s2++;
+
+ if (n < 0)
+ return 0;
+ else
+ return (ISALPHA (*s1) && ISALPHA (*s2)
+ ? lowcase (*s1) - lowcase (*s2)
+ : *s1 - *s2);
+}
+#endif
+
\f
static char searchar = '/'; /* use /.../ searches */
return NULL;
suffix += 1;
for (lang = lang_names; lang->name != NULL; lang++)
- if (lang->suffixes != NULL)
+ if (lang->suffixes != NULL) {
for (ext = lang->suffixes; *ext != NULL; ext++)
- if ((case_sensitive)
- ? streq (*ext, suffix)
- : strcaseeq (*ext, suffix))
+ if (case_sensitive) {
+ if (streq (*ext, suffix))
+ return lang;
+ } else if (strcaseeq (*ext, suffix))
return lang;
+ }
return NULL;
}
language *lang;
{
struct stat stat_buf;
- FILE *inf;
- fdesc *fdp;
- compressor *compr;
- char *compressed_name, *uncompressed_name;
- char *ext, *real_name;
+ FILE *inf = NULL;
+ fdesc *fdp = NULL;
+ compressor *compr = NULL;
+ char *compressed_name = NULL,
+ *uncompressed_name = NULL;
+ char *ext = NULL,
+ *real_name = NULL;
int retval;
canonicalize_filename (file);
error ("skipping inclusion of %s in self.", file);
return;
}
- if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
+ if ( get_compressor_from_suffix (file, &ext) == NULL)
{
- compressed_name = NULL;
real_name = uncompressed_name = savestr (file);
}
else
goto cleanup;
}
- if (stat (real_name, &stat_buf) != 0)
- {
- /* Reset real_name and try with a different name. */
- real_name = NULL;
- if (compressed_name != NULL) /* try with the given suffix */
+ compr = compressors;
+ do {
+ /* First try to open ... */
+ if (real_name == compressed_name)
{
- if (stat (uncompressed_name, &stat_buf) == 0)
- real_name = uncompressed_name;
+ char *cmd = concat (compr->command, " ", real_name);
+ inf = (FILE *) popen (cmd, "r");
+ free (cmd);
}
- else /* try all possible suffixes */
- {
- for (compr = compressors; compr->suffix != NULL; compr++)
+ else
+ inf = fopen (real_name, "r");
+ if ( inf != NULL ) {
+ /* Open was successfull, check it is a regular file */
+ if (stat (real_name, &stat_buf) == 0 &&
+ !S_ISREG (stat_buf.st_mode))
+ {
+ error ("skipping %s: it is not a regular file.",
+ real_name);
+ fclose(inf);
+ inf = NULL;
+ }
+ }
+ /* Not else from previous if because inner check may reset inf
+ to NULL, at which case we will want to try the next?
+ compressed filename... */
+ if ( inf == NULL ) {
+ /* Reset real_name and try with a different name. */
+ free(compressed_name);
+ real_name = NULL;
+ if (compressed_name != NULL)
+ /* try with the given suffix */
+ {
+ compressed_name = NULL;
+ real_name = uncompressed_name;
+ }
+ else if ( compr && compr->suffix != NULL )
+ /* try all possible suffixes */
{
compressed_name = concat (file, ".", compr->suffix);
- if (stat (compressed_name, &stat_buf) != 0)
- {
- free (compressed_name);
- compressed_name = NULL;
- }
- else
- {
- real_name = compressed_name;
- break;
- }
+ real_name = compressed_name;
+ compr++;
}
}
- if (real_name == NULL)
- {
- perror (file);
- goto cleanup;
- }
- } /* try with a different name */
-
- if (!S_ISREG (stat_buf.st_mode))
- {
- error ("skipping %s: it is not a regular file.", real_name);
- goto cleanup;
- }
- if (real_name == compressed_name)
- {
- char *cmd = concat (compr->command, " ", real_name);
- inf = (FILE *) popen (cmd, "r");
- free (cmd);
- }
- else
- inf = fopen (real_name, "r");
+ } while( inf == NULL && real_name != NULL);
if (inf == NULL)
{
perror (real_name);
{
len = strlen (cstack.cname[0]);
linebuffer_setlen (cn, len+1);
- strncpy (cn->buffer, cstack.cname[0],len+1);
+ xstrncpy (cn->buffer, cstack.cname[0],len+1);
}
for (i = 1; i < cstack.nl; i++)
{
{
fvdef = fvnone;
objdef = omethodtag;
- linebuffer_setlen (&token_name, len);
- strncpy (token_name.buffer, str, len);
+ linebuffer_setlen (&token_name, len+1);
+ xstrncpy (token_name.buffer, str, len+1);
token_name.buffer[len] = '\0';
return TRUE;
}
off += 1;
len -= 1;
}
- linebuffer_setlen (&token_name, len);
- strncpy (token_name.buffer,
- newlb.buffer + off, len);
- token_name.buffer[len] = '\0';
+ linebuffer_setlen (&token_name, len+1);
+ xstrncpy (token_name.buffer,
+ newlb.buffer + off, len+1);
if (defun)
while (--len >= 0)
if (token_name.buffer[len] == '_')
}
else
{
- linebuffer_setlen (&token_name, toklen);
- strncpy (token_name.buffer,
- newlb.buffer + tokoff, toklen);
+ linebuffer_setlen (&token_name, toklen+1);
+ xstrncpy (token_name.buffer,
+ newlb.buffer + tokoff, toklen+1);
token_name.buffer[toklen] = '\0';
/* Name macros and members. */
token.named = (structdef == stagseen
continue;
/* Save all values for later tagging. */
- linebuffer_setlen (&tline, lb.len);
- strncpy(tline.buffer, lb.buffer, lb.len-1);
+ linebuffer_setlen (&tline, lb.len+1);
+ xstrncpy(tline.buffer, lb.buffer, lb.len+1);
save_lineno = lineno;
save_lcno = linecharno;
name = tline.buffer + (dbp - lb.buffer);
else
for (end = dbp; *end != '\0' && intoken (*end); end++)
continue;
- linebuffer_setlen (&token_name, end - dbp);
- strncpy (token_name.buffer, dbp, end - dbp);
+ linebuffer_setlen (&token_name, end - dbp+1);
+ xstrncpy (token_name.buffer, dbp, end - dbp+1);
token_name.buffer[end - dbp] = '\0';
dbp = end;
else if (len + 1 > allocated)
xrnew (last, len + 1, char);
allocated = len + 1;
- strncpy (last, cp, len);
- last[len] = '\0';
+ xstrncpy (last, cp, len+1);
}
}
free (last);
else if (len + 1 > allocated)
xrnew (last, len + 1, char);
allocated = len + 1;
- strncpy (last, cp, len);
- last[len] = '\0';
+ xstrncpy (last, cp, allocated);
}
}
free (last);
/* Allocate space and do the substitutions. */
assert (size >= 0);
- result = xnew (size + 1, char);
+ size_t avail = size + 1;
+ result = xnew (avail, char);
for (t = result; *out != '\0'; out++)
if (*out == '\\' && ISDIGIT (*++out))
{
dig = *out - '0';
diglen = regs->end[dig] - regs->start[dig];
- strncpy (t, in + regs->start[dig], diglen);
+ xstrncpy (t, in + regs->start[dig], avail);
t += diglen;
+ avail -= diglen;
}
- else
+ else {
*t++ = *out;
+ avail --;
+ }
*t = '\0';
assert (t <= result + size);
if (need_filebuf /* we need filebuf for multi-line regexps */
&& chars_deleted > 0) /* not at EOF */
{
- while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */
- {
- /* Expand filebuf. */
+ size_t need = filebuf.len + lbp->len + 1; /* +1 for \n */
+ while (filebuf.size <= need )
filebuf.size *= 2;
- xrnew (filebuf.buffer, filebuf.size, char);
- }
- strncpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len);
+ /* Expand filebuf. */
+ xrnew (filebuf.buffer, filebuf.size, char);
+ xstrncpy (filebuf.buffer + filebuf.len, lbp->buffer, filebuf.size - filebuf.len);
filebuf.len += lbp->len;
filebuf.buffer[filebuf.len++] = '\n';
filebuf.buffer[filebuf.len] = '\0';
register char *dp;
dp = xnew (len + 1, char);
- strncpy (dp, cp, len);
+ xstrncpy (dp, cp, len+1);
dp[len] = '\0';
return dp;
}
-/*
- * Return the ptr in sp at which the character c last
- * appears; NULL if not found
- *
- * Identical to POSIX strrchr, included for portability.
- */
-static char *
-etags_strrchr (sp, c)
-register const char *sp;
-register int c;
-{
- register const char *r;
-
- r = NULL;
- do
- {
- if (*sp == c)
- r = sp;
- } while (*sp++);
- return (char *)r;
-}
-
-/*
- * Return the ptr in sp at which the character c first
- * appears; NULL if not found
- *
- * Identical to POSIX strchr, included for portability.
- */
-static char *
-etags_strchr (sp, c)
-register const char *sp;
-register int c;
-{
- do
- {
- if (*sp == c)
- return (char *)sp;
- } while (*sp++);
- return NULL;
-}
-
-/*
- * Compare two strings, ignoring case for alphabetic characters.
- *
- * Same as BSD's strcasecmp, included for portability.
- */
-static int
-etags_strcasecmp (s1, s2)
-register const char *s1;
-register const char *s2;
-{
- while (*s1 != '\0'
- && (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) == lowcase (*s2)
- : *s1 == *s2))
- s1++, s2++;
-
- return (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) - lowcase (*s2)
- : *s1 - *s2);
-}
-
-/*
- * Compare two strings, ignoring case for alphabetic characters.
- * Stop after a given number of characters
- *
- * Same as BSD's strncasecmp, included for portability.
- */
-static int
-etags_strncasecmp (s1, s2, n)
-register const char *s1;
-register const char *s2;
-register int n;
-{
- while (*s1 != '\0' && n-- > 0
- && (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) == lowcase (*s2)
- : *s1 == *s2))
- s1++, s2++;
-
- if (n < 0)
- return 0;
- else
- return (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) - lowcase (*s2)
- : *s1 - *s2);
-}
/* Skip spaces (end of string is not space), return new pointer. */
static char *
int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
char *result = xnew (len1 + len2 + len3 + 1, char);
- strncpy(result, s1, len1+1);
- strncpy(result + len1, s2, len2+1);
- strncpy(result + len1 + len2, s3, len3+1);
+ xstrncpy(result, s1, len1+1);
+ xstrncpy(result + len1, s2, len2+1);
+ xstrncpy(result + len1 + len2, s3, len3+1);
result[len1 + len2 + len3] = '\0';
return result;
res_left = 3 * i + strlen(fp);
res = xnew( res_left + 1, char);
res[0] = '\0';
- for ( ; i-- > 0 ; res_left -= 4 )
+ for ( ; i-- > 0 ; res_left -= 3 )
strncat(res, "../", res_left );
/* Add the file name relative to the common root of file and dir. */
while (cp >= res && !filename_is_absolute (cp));
if (cp < res)
cp = slashp; /* the absolute name begins with "/.." */
- strcpy (cp, slashp + 3);
+ slashp += 3;
+ memmove(cp, slashp,strlen(slashp)+1);
slashp = cp;
continue;
}
int toksize;
{
while (lbp->size <= toksize)
- {
lbp->size *= 2;
- xrnew (lbp->buffer, lbp->size, char);
- }
+ xrnew (lbp->buffer, lbp->size, char);
lbp->len = toksize;
}