Skip to content

Commit

Permalink
builtin: str.last_index(); pref: hide-auto-str;
Browse files Browse the repository at this point in the history
  • Loading branch information
medvednikov committed Mar 28, 2024
1 parent 85533fe commit acf0107
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 49 deletions.
1 change: 0 additions & 1 deletion examples/quadtree_demo/quadtree_demo.v
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions vlib/builtin/builtin.c.v
Expand Up @@ -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
Expand Down
15 changes: 7 additions & 8 deletions vlib/builtin/js/string.js.v
Expand Up @@ -750,20 +750,19 @@ 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 {
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
return s.last_index(needle)
}

// 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)
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
}

pub fn (s string) trim_space() string {
Expand Down
18 changes: 9 additions & 9 deletions vlib/builtin/string.v
Expand Up @@ -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
Expand Down Expand Up @@ -1223,20 +1223,20 @@ 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 {
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
return s.last_index(needle)
}

// 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)
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
}

// index_kmp does KMP search.
Expand Down
1 change: 1 addition & 0 deletions vlib/gg/draw.c.v
Expand Up @@ -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 {
Expand Down
54 changes: 28 additions & 26 deletions vlib/gg/image.c.v
Expand Up @@ -291,41 +291,43 @@ 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
}
}
if img.id >= ctx.image_cache.len {
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
}
}
}
Expand Down
1 change: 1 addition & 0 deletions vlib/gg/text_rendering.c.v
Expand Up @@ -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)
Expand Down
14 changes: 14 additions & 0 deletions vlib/net/http/download.v
Expand Up @@ -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)!
}
7 changes: 6 additions & 1 deletion vlib/orm/README.md
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions vlib/os/os.v
Expand Up @@ -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 '/'
}
Expand All @@ -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..]
}

Expand Down
2 changes: 1 addition & 1 deletion vlib/v/checker/checker.v
Expand Up @@ -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)..]
}

Expand Down
5 changes: 5 additions & 0 deletions vlib/v/gen/c/auto_str_methods.v
Expand Up @@ -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}},')

Expand Down
4 changes: 4 additions & 0 deletions vlib/v/pref/pref.c.v
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit acf0107

Please sign in to comment.