/* TODO: base dir must be a runtime setting */ char * compose_project_dir_from_name(const char * project_name) { const char * home_dir; char * project_dir; size_t home_dir_len; home_dir = getenv("HOME"); home_dir_len = strlen(home_dir); project_dir = malloc(home_dir_len + DEFAULT_PROJECT_BASE_DIR_LEN + max_escaped_length(strlen(project_name)) + 1); if (project_dir == NULL) { log_error("malloc() failed to allocate buffer for project dir"); return NULL; } memcpy(project_dir, home_dir, home_dir_len); memcpy(project_dir + home_dir_len, DEFAULT_PROJECT_BASE_DIR, DEFAULT_PROJECT_BASE_DIR_LEN); escape_simple(project_name, project_dir + home_dir_len + DEFAULT_PROJECT_BASE_DIR_LEN, LADISH_ESCAPE_FLAG_ALL); return project_dir; }
wchar_t *escape( const wchar_t *in_orig, escape_flags_t flags ) { const wchar_t *in = in_orig; bool escape_all = !! (flags & ESCAPE_ALL); bool no_quoted = !! (flags & ESCAPE_NO_QUOTED); bool no_tilde = !! (flags & ESCAPE_NO_TILDE); wchar_t *out; wchar_t *pos; int need_escape=0; int need_complex_escape=0; if( !in ) { debug( 0, L"%s called with null input", __func__ ); FATAL_EXIT(); } if( !no_quoted && (wcslen( in ) == 0) ) { out = wcsdup(L"''"); if( !out ) DIE_MEM(); return out; } out = (wchar_t *)malloc( sizeof(wchar_t)*(wcslen(in)*4 + 1)); pos = out; if( !out ) DIE_MEM(); while( *in != 0 ) { if( ( *in >= ENCODE_DIRECT_BASE) && ( *in < ENCODE_DIRECT_BASE+256) ) { int val = *in - ENCODE_DIRECT_BASE; int tmp; *(pos++) = L'\\'; *(pos++) = L'X'; tmp = val/16; *pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp; tmp = val%16; *pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp; need_escape=need_complex_escape=1; } else { wchar_t c = *in; switch( c ) { case L'\t': *(pos++) = L'\\'; *(pos++) = L't'; need_escape=need_complex_escape=1; break; case L'\n': *(pos++) = L'\\'; *(pos++) = L'n'; need_escape=need_complex_escape=1; break; case L'\b': *(pos++) = L'\\'; *(pos++) = L'b'; need_escape=need_complex_escape=1; break; case L'\r': *(pos++) = L'\\'; *(pos++) = L'r'; need_escape=need_complex_escape=1; break; case L'\x1b': *(pos++) = L'\\'; *(pos++) = L'e'; need_escape=need_complex_escape=1; break; case L'\\': case L'\'': { need_escape=need_complex_escape=1; if( escape_all ) *pos++ = L'\\'; *pos++ = *in; break; } case L'&': case L'$': case L' ': case L'#': case L'^': case L'<': case L'>': case L'(': case L')': case L'[': case L']': case L'{': case L'}': case L'?': case L'*': case L'|': case L';': case L'"': case L'%': case L'~': { if (! no_tilde || c != L'~') { need_escape=1; if( escape_all ) *pos++ = L'\\'; } *pos++ = *in; break; } default: { if( *in < 32 ) { if( *in <27 && *in > 0 ) { *(pos++) = L'\\'; *(pos++) = L'c'; *(pos++) = L'a' + *in -1; need_escape=need_complex_escape=1; break; } int tmp = (*in)%16; *pos++ = L'\\'; *pos++ = L'x'; *pos++ = ((*in>15)? L'1' : L'0'); *pos++ = tmp > 9? L'a'+(tmp-10):L'0'+tmp; need_escape=need_complex_escape=1; } else { *pos++ = *in; } break; } } } in++; } *pos = 0; /* Use quoted escaping if possible, since most people find it easier to read. */ if( !no_quoted && need_escape && !need_complex_escape && escape_all ) { free( out ); out = escape_simple( in_orig ); } return out; }