@@ -20,7 +20,7 @@ use crossterm::{
20
20
} ;
21
21
use event:: KeyModifiers ;
22
22
use objdiff_core:: {
23
- config:: ProjectConfig ,
23
+ config:: { ProjectConfig , ProjectObject } ,
24
24
diff,
25
25
diff:: display:: { display_diff, DiffText , HighlightKind } ,
26
26
obj,
@@ -45,33 +45,75 @@ pub struct Args {
45
45
#[ argp( option, short = 'u' ) ]
46
46
/// Unit name within project
47
47
unit : Option < String > ,
48
- #[ argp( option , short = 's' ) ]
48
+ #[ argp( positional ) ]
49
49
/// Function symbol to diff
50
50
symbol : String ,
51
51
}
52
52
53
53
pub fn run ( args : Args ) -> Result < ( ) > {
54
54
let ( target_path, base_path, project_config) =
55
55
match ( & args. target , & args. base , & args. project , & args. unit ) {
56
- ( Some ( t) , Some ( b) , _, _) => ( Some ( t. clone ( ) ) , Some ( b. clone ( ) ) , None ) ,
57
- ( _, _, Some ( p) , Some ( u) ) => {
56
+ ( Some ( t) , Some ( b) , None , None ) => ( Some ( t. clone ( ) ) , Some ( b. clone ( ) ) , None ) ,
57
+ ( None , None , p, u) => {
58
+ let project = match p {
59
+ Some ( project) => project. clone ( ) ,
60
+ _ => std:: env:: current_dir ( ) . context ( "Failed to get the current directory" ) ?,
61
+ } ;
58
62
let Some ( ( project_config, project_config_info) ) =
59
- objdiff_core:: config:: try_project_config ( p )
63
+ objdiff_core:: config:: try_project_config ( & project )
60
64
else {
61
- bail ! ( "Project config not found in {}" , p . display( ) )
65
+ bail ! ( "Project config not found in {}" , & project . display( ) )
62
66
} ;
63
67
let mut project_config = project_config. with_context ( || {
64
68
format ! ( "Reading project config {}" , project_config_info. path. display( ) )
65
69
} ) ?;
66
- let Some ( object) = project_config. objects . iter_mut ( ) . find ( |obj| obj. name ( ) == u)
67
- else {
68
- bail ! ( "Unit not found: {}" , u)
70
+ let object = {
71
+ let resolve_paths = |o : & mut ProjectObject | {
72
+ o. resolve_paths (
73
+ & project,
74
+ project_config. target_dir . as_deref ( ) ,
75
+ project_config. base_dir . as_deref ( ) ,
76
+ )
77
+ } ;
78
+ if let Some ( u) = u {
79
+ let Some ( object) =
80
+ project_config. objects . iter_mut ( ) . find ( |obj| obj. name ( ) == u)
81
+ else {
82
+ bail ! ( "Unit not found: {}" , u)
83
+ } ;
84
+ resolve_paths ( object) ;
85
+ object
86
+ } else {
87
+ let mut idx = None ;
88
+ let mut count = 0usize ;
89
+ for ( i, obj) in project_config. objects . iter_mut ( ) . enumerate ( ) {
90
+ resolve_paths ( obj) ;
91
+
92
+ if obj
93
+ . target_path
94
+ . as_deref ( )
95
+ . map ( |o| obj:: elf:: has_function ( o, & args. symbol ) )
96
+ . transpose ( ) ?
97
+ . unwrap_or_default ( )
98
+ {
99
+ idx = Some ( i) ;
100
+ count += 1 ;
101
+ if count > 1 {
102
+ break ;
103
+ }
104
+ }
105
+ }
106
+ match ( count, idx) {
107
+ ( 0 , None ) => bail ! ( "Symbol not found: {}" , & args. symbol) ,
108
+ ( 1 , Some ( i) ) => & mut project_config. objects [ i] ,
109
+ ( 2 .., Some ( _) ) => bail ! (
110
+ "Multiple instances of {} were found, try specifying a unit" ,
111
+ & args. symbol
112
+ ) ,
113
+ _ => unreachable ! ( ) ,
114
+ }
115
+ }
69
116
} ;
70
- object. resolve_paths (
71
- p,
72
- project_config. target_dir . as_deref ( ) ,
73
- project_config. base_dir . as_deref ( ) ,
74
- ) ;
75
117
let target_path = object. target_path . clone ( ) ;
76
118
let base_path = object. base_path . clone ( ) ;
77
119
( target_path, base_path, Some ( project_config) )
0 commit comments