//replace bad chars in filename CString FileSystem::MakeValidFilename(const char* filename, bool allowSlashes) { CString result = filename; for (char* p = result; *p; p++) { if (ReservedChar(*p)) { if (allowSlashes && (*p == PATH_SEPARATOR || *p == ALT_PATH_SEPARATOR)) { *p = PATH_SEPARATOR; continue; } *p = '_'; } } // remove trailing dots and spaces. they are not allowed in directory names on windows, // but we remove them on posix too, in a case the directory is accessed from windows via samba. for (int len = strlen(result); len > 0 && (result[len - 1] == '.' || result[len - 1] == ' '); len--) { result[len - 1] = '\0'; } // check if the filename starts with a reserved device name. // although these names are reserved only on Windows we adjust them on posix too, // in a case the directory is accessed from windows via samba. for (const char** ptr = RESERVED_DEVICE_NAMES; const char* reserved = *ptr; ptr++) { int len = strlen(reserved); if (!strncasecmp(result, reserved, len) && (result[len] == '.' || result[len] == '\0')) { result = CString::FormatStr("_%s", *result); break; } } return result; }
bool FileSystem::NeedLongPath(const char* path) { bool alreadyLongPath = !strncmp(path, "\\\\?\\", 4); if (alreadyLongPath) { return false; } if (strlen(path) > 260 - 14) { return true; } Tokenizer tok(path, "\\/"); for (int partNo = 0; const char* part = tok.Next(); partNo++) { // check if the file part starts with a reserved device name for (const char** ptr = RESERVED_DEVICE_NAMES; const char* reserved = *ptr; ptr++) { int len = strlen(reserved); if (!strncasecmp(part, reserved, len) && (part[len] == '.' || part[len] == '\0')) { return true; } } // check if the file part contains reserved characters for (const char* p = part; *p; p++) { if (ReservedChar(*p) && !(partNo == 0 && p == part + 1 && *p == ':')) { return true; } } } return false; }
bool StreamTokenizer::GetNext(Token *next) { if (!is_.good()) { eof_reached_ = true; return false; } // Get first character of next token. char c; bool is_whitespace = true; while (is_whitespace) { if (!ReadChar(&c)) { return false; } is_whitespace = isspace(c); // If we find a comment character, then read to the end of the line. if (!is_whitespace && c == '/' && is_.peek() == '/') { while (c != '\n') { if (!ReadChar(&c)) { return false; } } is_whitespace = true; } } // In case we're successful in reading the next token, we fill in // the two stream state data available now. next->start = num_read_ - 1; next->line_number = line_number_; bool next_tok_complete = false; next->tok.clear(); if (ReservedChar(c)) { next->tok += c; next_tok_complete = true; next->type = RESERVED_CHAR; } else if (c == '"') { // We've got a string literal, so keep reading characters, // until hitting a non-escaped double quote. streampos string_literal_start_pos = num_read_ - 1; bool found_closing_quote = false; while (is_.good()) { bool success = ReadChar(&c); if (success) { if (c == '"') { found_closing_quote = true; break; } else if (c == '\\') { success = ReadChar(&c); } } if (success) { next->tok += c; } } if (!found_closing_quote) { cerr << "StreamTokenizer: error: could not find closing " << "double quote for string literal beginning at stream index " << string_literal_start_pos << "; partial string literal read: \"" << next->tok << endl; throw std::runtime_error("unclosed string literal"); } next_tok_complete = true; next->type = STRING; } else { // This is a number, a reserved word or C++ identifier token, so // add first character; the remainder of the token will be handled // in the next block. next->tok += c; next->type = (c == '-' || (c >= '0' && c <= '9')) ? NUMBER : IDENTIFIER; } if (!next_tok_complete) { // The current token is a number, a reserved word or C++ // identifier, so we keep reading characters until hitting a // "reserved character", a whitespace character or EOF. bool done = false; while (!done && is_.good()) { // We don't call ReadChar below because the next character might // tell us that the current token has ended (i.e., if it's a // reserved character, a double quote or a whitespace // character). int peek = is_.peek(); if (peek != EOF) { char next_char = static_cast<char>(peek); if (ReservedChar(next_char) || next_char == '"' || isspace(next_char)) { // Now that we've finished reading something that is not a // string literal, change its type to be RESERVED_WORD if it // exactly matches something in the set of reserved words. if (reserved_words_.count(next->tok) != 0) { next->type = RESERVED_WORD; } done = true; } else { ReadChar(&c); next->tok += c; } } else { eof_reached_ = true; } } } // We're about to return a successfully read token, so we make sure to record // the stream position at this point in the Token object. next->curr_pos = num_read_; return true; }