Sfoglia il codice sorgente

Add `-target:<string>` fuzzy checking with "Did you mean" message

gingerBill 5 anni fa
parent
commit
b8d33165c9
3 ha cambiato i file con 67 aggiunte e 3 eliminazioni
  1. 2 3
      src/build_settings.cpp
  2. 26 0
      src/main.cpp
  3. 39 0
      src/string.cpp

+ 2 - 3
src/build_settings.cpp

@@ -225,14 +225,13 @@ struct NamedTargetMetrics {
 };
 
 gb_global NamedTargetMetrics named_targets[] = {
-	{ str_lit("essence_amd64"), &target_essence_amd64 },
 	{ str_lit("darwin_amd64"),  &target_darwin_amd64 },
+	{ str_lit("essence_amd64"), &target_essence_amd64 },
+	{ str_lit("js_wasm32"),     &target_js_wasm32 },
 	{ str_lit("linux_386"),     &target_linux_386 },
 	{ str_lit("linux_amd64"),   &target_linux_amd64 },
 	{ str_lit("windows_386"),   &target_windows_386 },
 	{ str_lit("windows_amd64"), &target_windows_amd64 },
-	{ str_lit("js_wasm32"),     &target_js_wasm32 },
-	{ str_lit("wasm32"),        &target_js_wasm32 },
 };
 
 NamedTargetMetrics *selected_target_metrics;

+ 26 - 0
src/main.cpp

@@ -992,7 +992,33 @@ bool parse_build_flags(Array<String> args) {
 							}
 
 							if (!found) {
+								struct DistanceAndTarget {
+									isize distance;
+									isize target_index;
+								};
+								DistanceAndTarget distances[gb_count_of(named_targets)] = {};
+								for (isize i = 0; i < gb_count_of(named_targets); i++) {
+									distances[i].target_index = i;
+									distances[i].distance = levenstein_distance_case_insensitive(str, named_targets[i].name);
+								}
+								gb_sort_array(distances, gb_count_of(distances), gb_isize_cmp(gb_offset_of(DistanceAndTarget, distance)));
+
 								gb_printf_err("Unknown target '%.*s'\n", LIT(str));
+
+								enum {MAX_SMALLEST_DISTANCE = 3};
+								if (distances[0].distance <= MAX_SMALLEST_DISTANCE) {
+									gb_printf_err("Did you mean:\n");
+									for (isize i = 0; i < gb_count_of(named_targets); i++) {
+										if (distances[i].distance > MAX_SMALLEST_DISTANCE) {
+											break;
+										}
+										gb_printf_err("\t%.*s\n", LIT(named_targets[distances[i].target_index].name));
+									}
+								}
+								gb_printf_err("All supported targets:\n");
+								for (isize i = 0; i < gb_count_of(named_targets); i++) {
+									gb_printf_err("\t%.*s\n", LIT(named_targets[i].name));
+								}
 								bad_flags = true;
 							}
 

+ 39 - 0
src/string.cpp

@@ -762,3 +762,42 @@ i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_retu
 	}
 	return 2;
 }
+
+
+isize levenstein_distance_case_insensitive(String const &a, String const &b) {
+	isize w = a.len+1;
+	isize h = b.len+1;
+	isize *matrix = gb_alloc_array(heap_allocator(), isize, w*h);
+	for (isize i = 0; i <= a.len; i++) {
+		matrix[i*w + 0] = i;
+	}
+	for (isize i = 0; i <= b.len; i++) {
+		matrix[0*w + i] = i;
+	}
+
+	for (isize i = 1; i <= a.len; i++) {
+		char a_c = gb_char_to_lower(cast(char)a.text[i-1]);
+		for (isize j = 1; j <= b.len; j++) {
+			char b_c = gb_char_to_lower(cast(char)b.text[j-1]);
+			if (a_c == b_c) {
+				matrix[i*w + j] = matrix[(i-1)*w + j-1];
+			} else {
+				isize remove = matrix[(i-1)*w + j] + 1;
+				isize insert = matrix[i*w + j-1] + 1;
+				isize substitute = matrix[(i-1)*w + j-1] + 1;
+				isize minimum = remove;
+				if (insert < minimum) {
+					minimum = insert;
+				}
+				if (substitute < minimum) {
+					minimum = substitute;
+				}
+				matrix[i*w + j] = minimum;
+			}
+		}
+	}
+
+	isize res = matrix[a.len*w + b.len];
+	gb_free(heap_allocator(), matrix);
+	return res;
+}