* [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool [not found] <1294829822-27938-1-git-send-email-mjt@tls.msk.ru> @ 2011-01-12 10:57 ` Michael Tokarev 2011-01-21 9:29 ` Kevin Wolf 2011-01-12 10:57 ` [Qemu-devel] [PATCH 2/3] use new path_has_protocol() in bdrv_find_protocol() Michael Tokarev 2011-01-12 10:57 ` [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs Michael Tokarev 2 siblings, 1 reply; 5+ messages in thread From: Michael Tokarev @ 2011-01-12 10:57 UTC (permalink / raw) To: qemu-devel; +Cc: Michael Tokarev Currently protocol: parsing in filenames is ad-hoc and scattered all around block.c. This is a first step to prepare for common parsing. Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> --- block.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index ff2795b..e5a6f60 100644 --- a/block.c +++ b/block.c @@ -90,9 +90,11 @@ int is_windows_drive(const char *filename) } #endif -/* check if the path starts with "<protocol>:" */ -static int path_has_protocol(const char *path) +/* check if the path starts with "<protocol>:" + * Return pointer to the leading colon or NULL */ +static char *path_has_protocol(const char *path) { + const char *p; #ifdef _WIN32 if (is_windows_drive(path) || is_windows_drive_prefix(path)) { @@ -100,7 +102,17 @@ static int path_has_protocol(const char *path) } #endif - return strchr(path, ':') != NULL; + p = path; + /* we allow [a-z_] for now */ + while((*p >= 'a' && *p <= 'z') || *p == '_') { + ++p; + } + +#define MAX_PROTO_LEN 31 + /* recognize non-empty string of max MAX_PROTO chars as protocol */ + return + *p == ':' && p > path && (p - path) <= MAX_PROTO_LEN ? + (char*)p : NULL; } int path_is_absolute(const char *path) -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool 2011-01-12 10:57 ` [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool Michael Tokarev @ 2011-01-21 9:29 ` Kevin Wolf 0 siblings, 0 replies; 5+ messages in thread From: Kevin Wolf @ 2011-01-21 9:29 UTC (permalink / raw) To: Michael Tokarev; +Cc: qemu-devel Am 12.01.2011 11:57, schrieb Michael Tokarev: > Currently protocol: parsing in filenames is ad-hoc and scattered all around > block.c. This is a first step to prepare for common parsing. > > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> > --- > block.c | 18 +++++++++++++++--- > 1 files changed, 15 insertions(+), 3 deletions(-) > > diff --git a/block.c b/block.c > index ff2795b..e5a6f60 100644 > --- a/block.c > +++ b/block.c > @@ -90,9 +90,11 @@ int is_windows_drive(const char *filename) > } > #endif > > -/* check if the path starts with "<protocol>:" */ > -static int path_has_protocol(const char *path) > +/* check if the path starts with "<protocol>:" > + * Return pointer to the leading colon or NULL */ > +static char *path_has_protocol(const char *path) > { > + const char *p; > #ifdef _WIN32 > if (is_windows_drive(path) || > is_windows_drive_prefix(path)) { > @@ -100,7 +102,17 @@ static int path_has_protocol(const char *path) > } > #endif > > - return strchr(path, ':') != NULL; > + p = path; > + /* we allow [a-z_] for now */ > + while((*p >= 'a' && *p <= 'z') || *p == '_') { Maybe qemu_isalnum(*p) || *p == '_' instead? We probably won't need uppercase letters, but digits are well possible. We'll have a hard time adding any characters here later as this will break previously working image filenames. > + ++p; > + } > + > +#define MAX_PROTO_LEN 31 > + /* recognize non-empty string of max MAX_PROTO chars as protocol */ > + return > + *p == ':' && p > path && (p - path) <= MAX_PROTO_LEN ? > + (char*)p : NULL; What's the point of MAX_PROTO_LEN? It just seems to make the handling even less consistent than it already is. Kevin ^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/3] use new path_has_protocol() in bdrv_find_protocol() [not found] <1294829822-27938-1-git-send-email-mjt@tls.msk.ru> 2011-01-12 10:57 ` [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool Michael Tokarev @ 2011-01-12 10:57 ` Michael Tokarev 2011-01-12 10:57 ` [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs Michael Tokarev 2 siblings, 0 replies; 5+ messages in thread From: Michael Tokarev @ 2011-01-12 10:57 UTC (permalink / raw) To: qemu-devel; +Cc: Michael Tokarev Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> --- block.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index e5a6f60..42d6ff1 100644 --- a/block.c +++ b/block.c @@ -314,7 +314,7 @@ static BlockDriver *find_hdev_driver(const char *filename) BlockDriver *bdrv_find_protocol(const char *filename) { BlockDriver *drv1; - char protocol[128]; + char protocol[MAX_PROTO_LEN+1]; int len; const char *p; @@ -332,14 +332,11 @@ BlockDriver *bdrv_find_protocol(const char *filename) return drv1; } - if (!path_has_protocol(filename)) { + p = path_has_protocol(filename); + if (!p) { return bdrv_find_format("file"); } - p = strchr(filename, ':'); - assert(p != NULL); len = p - filename; - if (len > sizeof(protocol) - 1) - len = sizeof(protocol) - 1; memcpy(protocol, filename, len); protocol[len] = '\0'; QLIST_FOREACH(drv1, &bdrv_drivers, list) { -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs [not found] <1294829822-27938-1-git-send-email-mjt@tls.msk.ru> 2011-01-12 10:57 ` [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool Michael Tokarev 2011-01-12 10:57 ` [Qemu-devel] [PATCH 2/3] use new path_has_protocol() in bdrv_find_protocol() Michael Tokarev @ 2011-01-12 10:57 ` Michael Tokarev 2011-01-21 10:07 ` Kevin Wolf 2 siblings, 1 reply; 5+ messages in thread From: Michael Tokarev @ 2011-01-12 10:57 UTC (permalink / raw) To: qemu-devel; +Cc: Michael Tokarev Currently the two routines tries to "understand" and skip <protocol>: prefix in path arguments are path_combine() and path_is_absolute() (the latter isn't used anywhere but in the former). This is wrong, since notion of absolute path is, at least, protocol-specific. The implementation is more wrong on windows where even non-absolute paths but with drive name (d:foo) should be treated as absolute, as in, one can't combine, say, c:\bar with d:foo forming c:\foo as path_combine() currently does. Introduce isslash() macro that works correctly on both windows and unix, use it in is_windows_drive_prefix() (since any form of slash can be used in constructs like //./), remove path_is_absolute() and hardcode the trivial (but right) condition in path_combine(), and simplify path_combine() further by removing <protocol>: handling and unifying shash searching. Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> --- block.c | 72 +++++++++++++++++++++----------------------------------------- 1 files changed, 25 insertions(+), 47 deletions(-) diff --git a/block.c b/block.c index 42d6ff1..31a821d 100644 --- a/block.c +++ b/block.c @@ -71,6 +71,9 @@ static BlockDriverState *bs_snapshots; static int use_bdrv_whitelist; #ifdef _WIN32 + +#define isslash(c) ((c) == '/' || (c) == '\\') + static int is_windows_drive_prefix(const char *filename) { return (((filename[0] >= 'a' && filename[0] <= 'z') || @@ -83,11 +86,17 @@ int is_windows_drive(const char *filename) if (is_windows_drive_prefix(filename) && filename[2] == '\0') return 1; - if (strstart(filename, "\\\\.\\", NULL) || - strstart(filename, "//./", NULL)) - return 1; + if (isslash(filename[0] && isslash(filename[1]) && + filename[2] == '.' && isslash(filename[3])) + return 1; /* special case: windows device "//./" */ return 0; } + +#else + +#define isslash(c) ((c) == '/') +#define is_windows_drive_prefix(filename) (0) + #endif /* check if the path starts with "<protocol>:" @@ -115,61 +124,30 @@ static char *path_has_protocol(const char *path) (char*)p : NULL; } -int path_is_absolute(const char *path) -{ - const char *p; -#ifdef _WIN32 - /* specific case for names like: "\\.\d:" */ - if (*path == '/' || *path == '\\') - return 1; -#endif - p = strchr(path, ':'); - if (p) - p++; - else - p = path; -#ifdef _WIN32 - return (*p == '/' || *p == '\\'); -#else - return (*p == '/'); -#endif -} - /* if filename is absolute, just copy it to dest. Otherwise, build a - path to it by considering it is relative to base_path. URL are - supported. */ + path to it by considering it is relative to base_path. + This is really about filenames not URLs - we don't support + <protocol>: prefix in filename since it makes no sense, especially + if the protocol in base_path is not the same as in filename. + */ void path_combine(char *dest, int dest_size, const char *base_path, const char *filename) { - const char *p, *p1; + const char *p; int len; if (dest_size <= 0) return; - if (path_is_absolute(filename)) { + /* on windows, d:filename should be treated as absolute too */ + if (isslash(filename[0]) || is_windows_drive_prefix(filename)) { pstrcpy(dest, dest_size, filename); } else { - p = strchr(base_path, ':'); - if (p) - p++; - else - p = base_path; - p1 = strrchr(base_path, '/'); -#ifdef _WIN32 - { - const char *p2; - p2 = strrchr(base_path, '\\'); - if (!p1 || p2 > p1) - p1 = p2; - } -#endif - if (p1) - p1++; - else - p1 = base_path; - if (p1 > p) - p = p1; + /* find last slash */ + p = base_path + strlen(base_path); + while(p >= base_path && !isslash(*p)) + --p; + p++; len = p - base_path; if (len > dest_size - 1) len = dest_size - 1; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs 2011-01-12 10:57 ` [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs Michael Tokarev @ 2011-01-21 10:07 ` Kevin Wolf 0 siblings, 0 replies; 5+ messages in thread From: Kevin Wolf @ 2011-01-21 10:07 UTC (permalink / raw) To: Michael Tokarev; +Cc: qemu-devel Am 12.01.2011 11:57, schrieb Michael Tokarev: > Currently the two routines tries to "understand" and skip <protocol>: > prefix in path arguments are path_combine() and path_is_absolute() > (the latter isn't used anywhere but in the former). This is wrong, > since notion of absolute path is, at least, protocol-specific. > > The implementation is more wrong on windows where even non-absolute > paths but with drive name (d:foo) should be treated as absolute, as > in, one can't combine, say, c:\bar with d:foo forming c:\foo as > path_combine() currently does. > > Introduce isslash() macro that works correctly on both windows and > unix, use it in is_windows_drive_prefix() (since any form of slash > can be used in constructs like //./), You're saying that \/.\ is a valid format for it? Wow... > remove path_is_absolute() and > hardcode the trivial (but right) condition in path_combine(), and > simplify path_combine() further by removing <protocol>: handling > and unifying shash searching. > > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> > --- > block.c | 72 +++++++++++++++++++++----------------------------------------- > 1 files changed, 25 insertions(+), 47 deletions(-) > > diff --git a/block.c b/block.c > index 42d6ff1..31a821d 100644 > --- a/block.c > +++ b/block.c > @@ -71,6 +71,9 @@ static BlockDriverState *bs_snapshots; > static int use_bdrv_whitelist; > > #ifdef _WIN32 > + > +#define isslash(c) ((c) == '/' || (c) == '\\') > + > static int is_windows_drive_prefix(const char *filename) > { > return (((filename[0] >= 'a' && filename[0] <= 'z') || > @@ -83,11 +86,17 @@ int is_windows_drive(const char *filename) > if (is_windows_drive_prefix(filename) && > filename[2] == '\0') > return 1; > - if (strstart(filename, "\\\\.\\", NULL) || > - strstart(filename, "//./", NULL)) > - return 1; > + if (isslash(filename[0] && isslash(filename[1]) && Missing bracket, doesn't even compile. > + filename[2] == '.' && isslash(filename[3])) > + return 1; /* special case: windows device "//./" */ Please add curly braces. > return 0; > } > + > +#else > + > +#define isslash(c) ((c) == '/') > +#define is_windows_drive_prefix(filename) (0) Please make this a function, for consistency and type checking. The compiler is going to inline it anyway. > + > #endif > > /* check if the path starts with "<protocol>:" > @@ -115,61 +124,30 @@ static char *path_has_protocol(const char *path) > (char*)p : NULL; > } > > -int path_is_absolute(const char *path) > -{ > - const char *p; > -#ifdef _WIN32 > - /* specific case for names like: "\\.\d:" */ > - if (*path == '/' || *path == '\\') > - return 1; > -#endif > - p = strchr(path, ':'); > - if (p) > - p++; > - else > - p = path; > -#ifdef _WIN32 > - return (*p == '/' || *p == '\\'); > -#else > - return (*p == '/'); > -#endif > -} > - > /* if filename is absolute, just copy it to dest. Otherwise, build a > - path to it by considering it is relative to base_path. URL are > - supported. */ > + path to it by considering it is relative to base_path. > + This is really about filenames not URLs - we don't support > + <protocol>: prefix in filename since it makes no sense, especially > + if the protocol in base_path is not the same as in filename. > + */ > void path_combine(char *dest, int dest_size, > const char *base_path, > const char *filename) > { > - const char *p, *p1; > + const char *p; > int len; > > if (dest_size <= 0) > return; > - if (path_is_absolute(filename)) { > + /* on windows, d:filename should be treated as absolute too */ > + if (isslash(filename[0]) || is_windows_drive_prefix(filename)) { > pstrcpy(dest, dest_size, filename); > } else { > - p = strchr(base_path, ':'); > - if (p) > - p++; > - else > - p = base_path; > - p1 = strrchr(base_path, '/'); > -#ifdef _WIN32 > - { > - const char *p2; > - p2 = strrchr(base_path, '\\'); > - if (!p1 || p2 > p1) > - p1 = p2; > - } > -#endif > - if (p1) > - p1++; > - else > - p1 = base_path; > - if (p1 > p) > - p = p1; > + /* find last slash */ > + p = base_path + strlen(base_path); > + while(p >= base_path && !isslash(*p)) > + --p; > + p++; Please add braces. > len = p - base_path; > if (len > dest_size - 1) > len = dest_size - 1; This changes the semantics to throw away the protocol. For example fat:foo combined with bar would have resulted in fat:bar previously and results in bar now. Probably not a problem. path_combine gets even worse if filename has a protocol. It's completely unclear what it's supposed to do with protocols anyway. Kevin ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-01-21 10:06 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <1294829822-27938-1-git-send-email-mjt@tls.msk.ru> 2011-01-12 10:57 ` [Qemu-devel] [PATCH 1/3] make path_has_protocol() to return pointer instead of bool Michael Tokarev 2011-01-21 9:29 ` Kevin Wolf 2011-01-12 10:57 ` [Qemu-devel] [PATCH 2/3] use new path_has_protocol() in bdrv_find_protocol() Michael Tokarev 2011-01-12 10:57 ` [Qemu-devel] [PATCH 3/3] make path_combine() especially for filenames, not URLs Michael Tokarev 2011-01-21 10:07 ` Kevin Wolf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).