Add support for generating ISO identifiers from ASCII strings.
This commit is contained in:
parent
315f1a1717
commit
8f7222609e
101
src/util.c
101
src/util.c
@ -15,6 +15,7 @@
|
|||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
int div_up(int n, int div)
|
int div_up(int n, int div)
|
||||||
{
|
{
|
||||||
@ -176,3 +177,103 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int valid_d_char(char c)
|
||||||
|
{
|
||||||
|
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_dirid(char *src, int maxlen)
|
||||||
|
{
|
||||||
|
size_t len, i;
|
||||||
|
|
||||||
|
len = strlen(src);
|
||||||
|
if (len > maxlen) {
|
||||||
|
src[maxlen] = '\0';
|
||||||
|
len = maxlen;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
char c = toupper(src[i]);
|
||||||
|
src[i] = valid_d_char(c) ? c : '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_1_fileid(char *src)
|
||||||
|
{
|
||||||
|
char *dot; /* Position of the last dot in the filename, will be used to
|
||||||
|
calculate lname and lext. */
|
||||||
|
int lname, lext, pos, i;
|
||||||
|
|
||||||
|
dot = strrchr(src, '.');
|
||||||
|
|
||||||
|
lext = dot ? strlen(dot + 1) : 0;
|
||||||
|
lname = strlen(src) - lext - (dot ? 1 : 0);
|
||||||
|
|
||||||
|
/* If we can't build a filename, return. */
|
||||||
|
if (lname == 0 && lext == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
/* Convert up to 8 characters of the filename. */
|
||||||
|
for (i = 0; i < lname && i < 8; i++) {
|
||||||
|
char c = toupper(src[i]);
|
||||||
|
src[pos++] = valid_d_char(c) ? c : '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This dot is mandatory, even if there is no extension. */
|
||||||
|
src[pos++] = '.';
|
||||||
|
|
||||||
|
/* Convert up to 3 characters of the extension, if any. */
|
||||||
|
for (i = 0; i < lext && i < 3; i++) {
|
||||||
|
char c = toupper(src[lname + 1 + i]);
|
||||||
|
src[pos++] = valid_d_char(c) ? c : '_';
|
||||||
|
}
|
||||||
|
src[pos] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_2_fileid(char *src)
|
||||||
|
{
|
||||||
|
char *dot;
|
||||||
|
int lname, lext, lnname, lnext, pos, i;
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dot = strrchr(src, '.');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the maximum length can be divided freely over the name and
|
||||||
|
* extension, we need to calculate their new lengths (lnname and
|
||||||
|
* lnext). If the original filename is too long, we start by trimming
|
||||||
|
* the extension, but keep a minimum extension length of 3.
|
||||||
|
*/
|
||||||
|
if (dot == NULL || *(dot + 1) == '\0') {
|
||||||
|
lname = strlen(src);
|
||||||
|
lnname = (lname > 30) ? 30 : lname;
|
||||||
|
lext = lnext = 0;
|
||||||
|
} else {
|
||||||
|
lext = strlen(dot + 1);
|
||||||
|
lname = strlen(src) - lext - 1;
|
||||||
|
lnext = (strlen(src) > 31 && lext > 3)
|
||||||
|
? (lname < 27 ? 30 - lname : 3) : lext;
|
||||||
|
lnname = (strlen(src) > 31) ? 30 - lnext : lname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lnname == 0 && lnext == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
/* Convert up to lnname characters of the filename. */
|
||||||
|
for (i = 0; i < lnname; i++) {
|
||||||
|
char c = toupper(src[i]);
|
||||||
|
src[pos++] = valid_d_char(c) ? c : '_';
|
||||||
|
}
|
||||||
|
src[pos++] = '.';
|
||||||
|
/* Convert up to lnext characters of the extension, if any. */
|
||||||
|
for (i = 0; i < lnext; i++) {
|
||||||
|
char c = toupper(src[lname + 1 + i]);
|
||||||
|
src[pos++] = valid_d_char(c) ? c : '_';
|
||||||
|
}
|
||||||
|
src[pos] = '\0';
|
||||||
|
}
|
||||||
|
43
src/util.h
43
src/util.h
@ -13,6 +13,49 @@ extern inline int div_up(int n, int div);
|
|||||||
|
|
||||||
extern inline int round_up(int n, int mul);
|
extern inline int round_up(int n, int mul);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a given string from any input charset to ASCII
|
||||||
|
*
|
||||||
|
* @param icharset
|
||||||
|
* Input charset. Must be supported by iconv
|
||||||
|
* @param input
|
||||||
|
* Input string
|
||||||
|
* @param ouput
|
||||||
|
* Location where the pointer to the ouput string will be stored
|
||||||
|
* @return
|
||||||
|
* 1 on success, < 0 on error
|
||||||
|
*/
|
||||||
int str2ascii(const char *icharset, const char *input, char **output);
|
int str2ascii(const char *icharset, const char *input, char **output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a given string is a valid ISO directory identifier, modifying
|
||||||
|
* it if needed.
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* The identifier, in ASCII encoding. It may be modified by the function.
|
||||||
|
* @param maxlen
|
||||||
|
* Maximum length supported by current iso level.
|
||||||
|
*/
|
||||||
|
void iso_dirid(char *src, int maxlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a given string is a valid ISO level 1 file identifier, in 8.3
|
||||||
|
* format, modifying it if needed.
|
||||||
|
* Note that version number is not added to the file name
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* The identifier, in ASCII encoding. It may be modified by the function.
|
||||||
|
*/
|
||||||
|
void iso_1_fileid(char *src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a given string is a valid ISO level 2 file identifier, modifying it
|
||||||
|
* if needed.
|
||||||
|
* Note that version number is not added to the file name
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* The identifier, in ASCII encoding. It may be modified by the function.
|
||||||
|
*/
|
||||||
|
void iso_2_fileid(char *src);
|
||||||
|
|
||||||
#endif /*LIBISO_UTIL_H_*/
|
#endif /*LIBISO_UTIL_H_*/
|
||||||
|
Loading…
Reference in New Issue
Block a user