jehanne/sys/src/lib/jehanne/port/quote.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, &quotelen) == 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, &quotelen) == 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;
}