bool
var_is_valid_name (const char *name, bool issue_error)
{
+ bool plausible;
size_t length, i;
assert (name != NULL);
+ /* Note that strlen returns number of BYTES, not the number of
+ CHARACTERS */
length = strlen (name);
- if (length < 1)
- {
- if (issue_error)
- msg (SE, _("Variable name cannot be empty string."));
- return false;
- }
- else if (length > LONG_NAME_LEN)
+
+ plausible = var_is_plausible_name(name, issue_error);
+
+ if ( ! plausible )
+ return false;
+
+
+ if (!lex_is_id1 (name[0]))
{
if (issue_error)
- msg (SE, _("Variable name %s exceeds %d-character limit."),
- name, (int) LONG_NAME_LEN);
+ msg (SE, _("Character `%c' (in %s), may not appear "
+ "as the first character in a variable name."),
+ name[0], name);
return false;
}
+
for (i = 0; i < length; i++)
+ {
if (!lex_is_idn (name[i]))
{
if (issue_error)
name[i], name);
return false;
}
-
- if (!lex_is_id1 (name[0]))
+ }
+
+ return true;
+}
+
+/*
+ Returns true if NAME is an plausible name for a variable,
+ false otherwise. If ISSUE_ERROR is true, issues an
+ explanatory error message on failure.
+ This function makes no use of LC_CTYPE.
+*/
+bool
+var_is_plausible_name (const char *name, bool issue_error)
+{
+ size_t length;
+
+ assert (name != NULL);
+
+ /* Note that strlen returns number of BYTES, not the number of
+ CHARACTERS */
+ length = strlen (name);
+ if (length < 1)
{
if (issue_error)
- msg (SE, _("Character `%c' (in %s), may not appear "
- "as the first character in a variable name."),
- name[0], name);
+ msg (SE, _("Variable name cannot be empty string."));
+ return false;
+ }
+ else if (length > LONG_NAME_LEN)
+ {
+ if (issue_error)
+ msg (SE, _("Variable name %s exceeds %d-character limit."),
+ name, (int) LONG_NAME_LEN);
return false;
}
var_set_short_name (struct variable *v, const char *short_name)
{
assert (v != NULL);
- assert (short_name[0] == '\0' || var_is_valid_name (short_name, false));
+ assert (short_name[0] == '\0' || var_is_plausible_name (short_name, false));
str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
str_uppercase (v->short_name);
abort ();
}
}
+
+
+/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
+ Each 256th byte, which is expected to be a ' ', is deleted.
+ DST is then truncated to DST_SIZE bytes or padded on the right with
+ spaces as needed. */
+void
+copy_demangle (char *dst, size_t dst_size,
+ const char *src, size_t src_size)
+{
+ int src_bytes_left = src_size;
+ int dst_bytes_left = dst_size;
+ const char *s = src;
+ char *d = dst;
+
+
+ while( src_bytes_left > 0 )
+ {
+ const size_t s_chunk = min(MAX_LONG_STRING, src_bytes_left);
+ const size_t d_chunk = min(MAX_LONG_STRING, dst_bytes_left);
+
+ assert ( d < dst + dst_size);
+
+ buf_copy_rpad (d, d_chunk,
+ s, s_chunk);
+
+ d += d_chunk;
+ s += s_chunk;
+ src_bytes_left -= s_chunk;
+ dst_bytes_left -= d_chunk;
+
+ if ( src_bytes_left > 0 && ! (++s - src) % (MAX_LONG_STRING+1) )
+ {
+ if ( *s != ' ')
+ msg(MW, _("Expected a space in very long string"));
+ src_bytes_left--;
+ }
+ }
+}
+
+/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
+ DST is rounded up to the nearest 8 byte boundary.
+ A space is inserted at each 256th byte.
+ DST is then truncated to DST_SIZE bytes or padded on the right with
+ spaces as needed. */
+void
+copy_mangle (char *dst, size_t dst_size,
+ const char *src, size_t src_size)
+{
+ int src_bytes_left = src_size;
+ int dst_bytes_left = dst_size;
+ const char *s = src;
+ char *d = dst;
+
+ memset(dst, ' ', dst_size);
+
+ while( src_bytes_left > 0 )
+ {
+ const size_t s_chunk = min(MAX_LONG_STRING, src_bytes_left);
+ const size_t d_chunk = min(MAX_LONG_STRING, dst_bytes_left);
+
+ buf_copy_rpad (d, d_chunk, s, s_chunk);
+
+ d += d_chunk;
+ s += s_chunk;
+ src_bytes_left -= s_chunk;
+ dst_bytes_left -= d_chunk;
+
+ if ( dst_bytes_left > 0 && 0 == ( d + 1 - dst ) % (MAX_LONG_STRING + 1) )
+ {
+ memset(d, ' ', 1);
+ d++;
+ dst_bytes_left--;
+ }
+ }
+}
+
+/* Return the number of bytes used when writing case_data for a variable
+ of WIDTH */
+int
+width_to_bytes(int width)
+{
+ const int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ;
+ const int remainder = width - (chunks * EFFECTIVE_LONG_STRING_LENGTH) ;
+ int bytes, mod8;
+
+ assert (width >= 0);
+
+ if ( width == 0 )
+ return MAX_SHORT_STRING ;
+
+ if ( width <= MAX_LONG_STRING)
+ return MAX_SHORT_STRING * DIV_RND_UP(width, MAX_SHORT_STRING);
+
+
+ bytes = remainder + (chunks * (MAX_LONG_STRING + 1) );
+
+ /* Round up to the nearest 8 */
+ mod8 = bytes % MAX_SHORT_STRING;
+
+ if ( mod8 )
+ bytes += MAX_SHORT_STRING - mod8;
+
+ assert( bytes % MAX_SHORT_STRING == 0 );
+
+ return bytes;
+}
+