147 lines
2.8 KiB
C
147 lines
2.8 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
|
|
int (*doquote)(int);
|
|
|
|
extern int _needsquotes(const char*, int*);
|
|
extern int _runeneedsquotes(const Rune*, int*);
|
|
|
|
char*
|
|
jehanne_unquotestrdup(const char *s)
|
|
{
|
|
char *s1, *t, *ret;
|
|
int quoting;
|
|
|
|
ret = s1 = jehanne_strdup(s); /* return unquoted copy */
|
|
if(ret == nil)
|
|
return ret;
|
|
quoting = 0;
|
|
t = s1; /* s1 is output string, t is input string */
|
|
while(*t!='\0' && (quoting || (*t!=' ' && *t!='\t'))){
|
|
if(*t != '\''){
|
|
*s1++ = *t++;
|
|
continue;
|
|
}
|
|
/* *t is a quote */
|
|
if(!quoting){
|
|
quoting = 1;
|
|
t++;
|
|
continue;
|
|
}
|
|
/* quoting and we're on a quote */
|
|
if(t[1] != '\''){
|
|
/* end of quoted section; absorb closing quote */
|
|
t++;
|
|
quoting = 0;
|
|
continue;
|
|
}
|
|
/* doubled quote; fold one quote into two */
|
|
t++;
|
|
*s1++ = *t++;
|
|
}
|
|
if(t != s1)
|
|
jehanne_memmove(s1, t, jehanne_strlen(t)+1);
|
|
return ret;
|
|
}
|
|
|
|
Rune*
|
|
jehanne_unquoterunestrdup(const Rune *s)
|
|
{
|
|
Rune *s1, *t, *ret;
|
|
int quoting;
|
|
|
|
ret = s1 = jehanne_runestrdup(s); /* return unquoted copy */
|
|
if(ret == nil)
|
|
return ret;
|
|
quoting = 0;
|
|
t = s1; /* s1 is output string, t is input string */
|
|
while(*t!='\0' && (quoting || (*t!=' ' && *t!='\t'))){
|
|
if(*t != '\''){
|
|
*s1++ = *t++;
|
|
continue;
|
|
}
|
|
/* *t is a quote */
|
|
if(!quoting){
|
|
quoting = 1;
|
|
t++;
|
|
continue;
|
|
}
|
|
/* quoting and we're on a quote */
|
|
if(t[1] != '\''){
|
|
/* end of quoted section; absorb closing quote */
|
|
t++;
|
|
quoting = 0;
|
|
continue;
|
|
}
|
|
/* doubled quote; fold one quote into two */
|
|
t++;
|
|
*s1++ = *t++;
|
|
}
|
|
if(t != s1)
|
|
jehanne_memmove(s1, t, (jehanne_runestrlen(t)+1)*sizeof(Rune));
|
|
return ret;
|
|
}
|
|
|
|
char*
|
|
jehanne_quotestrdup(const char *s)
|
|
{
|
|
const char *t;
|
|
char *u, *ret;
|
|
int quotelen;
|
|
Rune r;
|
|
|
|
if(_needsquotes(s, "elen) == 0)
|
|
return jehanne_strdup(s);
|
|
|
|
ret = jehanne_malloc(quotelen+1);
|
|
if(ret == nil)
|
|
return nil;
|
|
u = ret;
|
|
*u++ = '\'';
|
|
for(t=s; *t; t++){
|
|
r = *t;
|
|
if(r == L'\'')
|
|
*u++ = r; /* double the quote */
|
|
*u++ = r;
|
|
}
|
|
*u++ = '\'';
|
|
*u = '\0';
|
|
return ret;
|
|
}
|
|
|
|
Rune*
|
|
jehanne_quoterunestrdup(const Rune *s)
|
|
{
|
|
const Rune *t;
|
|
Rune *u, *ret;
|
|
int quotelen;
|
|
Rune r;
|
|
|
|
if(_runeneedsquotes(s, "elen) == 0)
|
|
return jehanne_runestrdup(s);
|
|
|
|
ret = jehanne_malloc((quotelen+1)*sizeof(Rune));
|
|
if(ret == nil)
|
|
return nil;
|
|
u = ret;
|
|
*u++ = '\'';
|
|
for(t=s; *t; t++){
|
|
r = *t;
|
|
if(r == L'\'')
|
|
*u++ = r; /* double the quote */
|
|
*u++ = r;
|
|
}
|
|
*u++ = '\'';
|
|
*u = '\0';
|
|
return ret;
|
|
}
|