mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
builtin: str.last_index(); pref: hide-auto-str;
This commit is contained in:
parent
85533fe178
commit
acf0107493
13 changed files with 82 additions and 49 deletions
|
@ -118,7 +118,6 @@ fn main() {
|
|||
bg_color: gx.white
|
||||
width: win_width
|
||||
height: win_height
|
||||
use_ortho: true
|
||||
create_window: true
|
||||
window_title: 'Quadtree Demo'
|
||||
frame_fn: frame
|
||||
|
|
|
@ -269,6 +269,9 @@ pub fn println(s string) {
|
|||
println('println(NIL)')
|
||||
return
|
||||
}
|
||||
$if noprintln ? {
|
||||
return
|
||||
}
|
||||
$if android && !termux {
|
||||
C.android_print(C.stdout, c'%.*s\n', s.len, s.str)
|
||||
return
|
||||
|
|
|
@ -750,7 +750,14 @@ fn (s string) index_last_(p string) int {
|
|||
}
|
||||
|
||||
// index_last returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[deprecated: 'use `.last_index(needle string)` instead']
|
||||
pub fn (s string) index_last(needle string) ?int {
|
||||
return s.last_index(needle)
|
||||
}
|
||||
|
||||
// last_index returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[inline]
|
||||
pub fn (s string) last_index(needle string) ?int {
|
||||
idx := s.index_last_(needle)
|
||||
if idx == -1 {
|
||||
return none
|
||||
|
@ -758,14 +765,6 @@ pub fn (s string) index_last(needle string) ?int {
|
|||
return idx
|
||||
}
|
||||
|
||||
// last_index returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[deprecated: 'use `.index_last(needle string)` instead']
|
||||
@[deprecated_after: '2023-12-18']
|
||||
@[inline]
|
||||
pub fn (s string) last_index(needle string) ?int {
|
||||
return s.index_last(needle)
|
||||
}
|
||||
|
||||
pub fn (s string) trim_space() string {
|
||||
res := ''
|
||||
#res.str = s.str.trim()
|
||||
|
|
|
@ -1090,7 +1090,7 @@ pub fn (s string) substr(start int, _end int) string {
|
|||
end := if _end == max_int { s.len } else { _end } // max_int
|
||||
$if !no_bounds_checking {
|
||||
if start > end || start > s.len || end > s.len || start < 0 || end < 0 {
|
||||
panic('substr(${start}, ${end}) out of bounds (len=${s.len})')
|
||||
panic('substr(${start}, ${end}) out of bounds (len=${s.len}) s="${s}"')
|
||||
}
|
||||
}
|
||||
len := end - start
|
||||
|
@ -1223,7 +1223,15 @@ pub fn (s string) index(p string) ?int {
|
|||
}
|
||||
|
||||
// index_last returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[deprecated: 'use `.last_index(needle string)` instead']
|
||||
@[deprecated_after: '2024-03-27']
|
||||
pub fn (s string) index_last(needle string) ?int {
|
||||
return s.last_index(needle)
|
||||
}
|
||||
|
||||
// last_index returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[inline]
|
||||
pub fn (s string) last_index(needle string) ?int {
|
||||
idx := s.index_last_(needle)
|
||||
if idx == -1 {
|
||||
return none
|
||||
|
@ -1231,14 +1239,6 @@ pub fn (s string) index_last(needle string) ?int {
|
|||
return idx
|
||||
}
|
||||
|
||||
// last_index returns the position of the first character of the *last* occurrence of the `needle` string in `s`.
|
||||
@[deprecated: 'use `.index_last(needle string)` instead']
|
||||
@[deprecated_after: '2023-12-18']
|
||||
@[inline]
|
||||
pub fn (s string) last_index(needle string) ?int {
|
||||
return s.index_last(needle)
|
||||
}
|
||||
|
||||
// index_kmp does KMP search.
|
||||
@[direct_array_access; manualfree]
|
||||
fn (s string) index_kmp(p string) int {
|
||||
|
|
|
@ -54,6 +54,7 @@ pub fn (ctx &Context) draw_line(x f32, y f32, x2 f32, y2 f32, c gx.Color) {
|
|||
$if macos {
|
||||
if ctx.native_rendering {
|
||||
// Make the line more clear on hi dpi screens: draw a rectangle
|
||||
// TODO this is broken if the line's x1 != x2
|
||||
mut width := math.abs(x2 - x)
|
||||
mut height := math.abs(y2 - y)
|
||||
if width == 0 {
|
||||
|
|
|
@ -291,9 +291,9 @@ pub fn (ctx &Context) draw_image_with_config(config DrawImageConfig) {
|
|||
if config.img_id > 0 {
|
||||
img = &ctx.image_cache[config.img_id]
|
||||
} else {
|
||||
//$if !noggverbose ? {
|
||||
eprintln('gg: failed to get image to draw natively')
|
||||
//}
|
||||
$if !noggverbose ? {
|
||||
eprintln('gg: failed to get image to draw natively')
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -301,31 +301,33 @@ pub fn (ctx &Context) draw_image_with_config(config DrawImageConfig) {
|
|||
eprintln('gg: draw_image() bad img id ${img.id} (img cache len = ${ctx.image_cache.len})')
|
||||
return
|
||||
}
|
||||
if ctx.native_rendering {
|
||||
if img.width == 0 {
|
||||
println('w=0')
|
||||
return
|
||||
}
|
||||
if !os.exists(img.path) {
|
||||
println('not exist path')
|
||||
return
|
||||
}
|
||||
x := config.img_rect.x
|
||||
y := config.img_rect.y
|
||||
width := if config.img_rect.width == 0 {
|
||||
f32(img.width)
|
||||
} else {
|
||||
config.img_rect.width
|
||||
}
|
||||
height := if config.img_rect.height == 0 {
|
||||
f32(img.height)
|
||||
} else {
|
||||
config.img_rect.height
|
||||
}
|
||||
C.darwin_draw_image(x, ctx.height - (y + config.img_rect.height),
|
||||
width, height, img)
|
||||
if img.width == 0 {
|
||||
println('w=0')
|
||||
return
|
||||
}
|
||||
if !os.exists(img.path) {
|
||||
println('not exist path')
|
||||
return
|
||||
}
|
||||
x := config.img_rect.x
|
||||
y := config.img_rect.y
|
||||
width := if config.img_rect.width == 0 {
|
||||
// Calculate the width by dividing it by the height ratio.
|
||||
// e.g. the original image is 100x100, we're drawing 0x20. Find the ratio (5)
|
||||
// by dividing the height 100 by 20, and then divide the width by 5.
|
||||
f32(img.width / (img.height / config.img_rect.height))
|
||||
} else {
|
||||
config.img_rect.width
|
||||
}
|
||||
height := if config.img_rect.height == 0 {
|
||||
// Same as above.
|
||||
f32(img.height / (img.width / config.img_rect.width))
|
||||
} else {
|
||||
config.img_rect.height
|
||||
}
|
||||
C.darwin_draw_image(x, ctx.height - (y + config.img_rect.height), width,
|
||||
height, img)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,6 +186,7 @@ pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) {
|
|||
if ctx.native_rendering {
|
||||
if cfg.align == gx.align_right {
|
||||
width := ctx.text_width(text_)
|
||||
// println('draw text ctx.height = ${ctx.height}')
|
||||
C.darwin_draw_string(x - width, ctx.height - y, text_, cfg)
|
||||
} else {
|
||||
C.darwin_draw_string(x, ctx.height - y, text_, cfg)
|
||||
|
|
|
@ -25,3 +25,17 @@ pub fn download_file(url string, out_file_path string) ! {
|
|||
// type DownloadChunkFn = fn (written int)
|
||||
// type DownloadFinishedFn = fn ()
|
||||
// pub fn download_file_with_progress(url string, out_file_path string, cb_chunk DownloadChunkFn, cb_finished DownloadFinishedFn)
|
||||
|
||||
pub fn download_file_with_cookies(url string, out_file_path string, cookies map[string]string) ! {
|
||||
$if debug_http ? {
|
||||
println('http.download_file url=${url} out_file_path=${out_file_path}')
|
||||
}
|
||||
s := fetch(method: .get, url: url, cookies: cookies) or { return err }
|
||||
if s.status() != .ok {
|
||||
return error('received http code ${s.status_code}')
|
||||
}
|
||||
$if debug_http ? {
|
||||
println('http.download_file saving ${s.body.len} bytes')
|
||||
}
|
||||
os.write_file(out_file_path, s.body)!
|
||||
}
|
||||
|
|
|
@ -81,17 +81,22 @@ foo := Foo{
|
|||
]
|
||||
}
|
||||
|
||||
sql db {
|
||||
foo_id := sql db {
|
||||
insert foo into Foo
|
||||
}!
|
||||
```
|
||||
|
||||
If the `id` field is marked as `serial` and `primary`, the insert expression
|
||||
returns the database ID of the newly added object. Getting an ID of a newly
|
||||
added DB row is often useful.
|
||||
|
||||
When inserting, `[sql: serial]` fields, and fields with a `[default: 'raw_sql']`
|
||||
attribute are not sent to the database when the value being sent is the default
|
||||
for the V struct field (e.g., 0 int, or an empty string). This allows the
|
||||
database to insert default values for auto-increment fields and where you have
|
||||
specified a default.
|
||||
|
||||
|
||||
### Update
|
||||
|
||||
```v ignore
|
||||
|
|
|
@ -274,7 +274,7 @@ pub fn dir(opath string) string {
|
|||
}
|
||||
other_separator := if path_separator == '/' { '\\' } else { '/' }
|
||||
path := opath.replace(other_separator, path_separator)
|
||||
pos := path.index_last(path_separator) or { return '.' }
|
||||
pos := path.last_index(path_separator) or { return '.' }
|
||||
if pos == 0 && path_separator == '/' {
|
||||
return '/'
|
||||
}
|
||||
|
@ -296,10 +296,10 @@ pub fn base(opath string) string {
|
|||
}
|
||||
if path.ends_with(path_separator) {
|
||||
path2 := path[..path.len - 1]
|
||||
pos := path2.index_last(path_separator) or { return path2.clone() }
|
||||
pos := path2.last_index(path_separator) or { return path2.clone() }
|
||||
return path2[pos + 1..]
|
||||
}
|
||||
pos := path.index_last(path_separator) or { return path.clone() }
|
||||
pos := path.last_index(path_separator) or { return path.clone() }
|
||||
return path[pos + 1..]
|
||||
}
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ fn (mut c Checker) check_valid_snake_case(name string, identifier string, pos to
|
|||
}
|
||||
|
||||
fn stripped_name(name string) string {
|
||||
idx := name.index_last('.') or { -1 }
|
||||
idx := name.last_index('.') or { -1 }
|
||||
return name[(idx + 1)..]
|
||||
}
|
||||
|
||||
|
|
|
@ -928,6 +928,11 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin
|
|||
}
|
||||
}
|
||||
}
|
||||
// -hide-auto-str hides potential sensitive struct data from resulting binary files
|
||||
if g.pref.hide_auto_str {
|
||||
fn_body.writeln('\tstring res = { .str ="str() used with -hide-auto-str", .len=30 }; return res;')
|
||||
return
|
||||
}
|
||||
fn_body.writeln('\tstring res = str_intp( ${(info.fields.len - field_skips.len) * 4 + 3}, _MOV((StrIntpData[]){')
|
||||
fn_body.writeln('\t\t{_SLIT("${clean_struct_v_type_name}{\\n"), 0, {.d_c=0}},')
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ pub mut:
|
|||
profile_fns []string // when set, profiling will be off by default, but inside these functions (and what they call) it will be on.
|
||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
||||
hide_auto_str bool // `v -hide-auto-str program.v`, doesn't generate str() with struct data
|
||||
// Note: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files,
|
||||
// which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
|
||||
sanitize bool // use Clang's new "-fsanitize" option
|
||||
|
@ -642,6 +643,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
|
|||
'-obf', '-obfuscate' {
|
||||
res.obfuscate = true
|
||||
}
|
||||
'-hide-auto-str' {
|
||||
res.hide_auto_str = true
|
||||
}
|
||||
'-translated' {
|
||||
res.translated = true
|
||||
res.gc_mode = .no_gc // no gc in c2v'ed code, at least for now
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue