export sl_did_you_mean that uses OptimalStringAlignmentDistance to propose an alternative
This commit is contained in:
		
							
								
								
									
										84
									
								
								lib/sl/sl.c
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								lib/sl/sl.c
									
									
									
									
									
								
							| @@ -396,3 +396,87 @@ sl_slc_help (SL_cmd *cmds, int argc, char **argv) | |||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* OptimalStringAlignmentDistance */ | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | osad(const char *s1, const char *s2) | ||||||
|  | { | ||||||
|  |     size_t l1 = strlen(s1), l2 = strlen(s2), i, j; | ||||||
|  |     int *row0, *row1, *row2, *tmp, cost; | ||||||
|  |  | ||||||
|  |     row0 = calloc(sizeof(int), l2 + 1); | ||||||
|  |     row1 = calloc(sizeof(int), l2 + 1); | ||||||
|  |     row2 = calloc(sizeof(int), l2 + 1); | ||||||
|  |  | ||||||
|  |     for (j = 0; j < l2 + 1; j++) | ||||||
|  |         row1[j] = j; | ||||||
|  |  | ||||||
|  |     for (i = 0; i < l1; i++) { | ||||||
|  |  | ||||||
|  |         row2[0] = i + 1; | ||||||
|  |  | ||||||
|  |         for (j = 0; j < l2; j++) { | ||||||
|  |  | ||||||
|  | 	    row2[j + 1] = row1[j] + (s1[i] != s2[j]); /* substitute */ | ||||||
|  | 	     | ||||||
|  | 	    if (row2[j + 1] > row1[j + 1] + 1) /* delete */ | ||||||
|  | 		row2[j + 1] = row1[j + 1] + 1; | ||||||
|  | 	    if (row2[j + 1] > row2[j] + 1) /* insert */ | ||||||
|  | 		row2[j + 1] = row2[j] + 1; | ||||||
|  | 	    if (j > 0 && i > 0 && s1[i - 1] != s2[j - 1] && s1[i - 1] == s2[j] && s1[i] == s2[j - 1] && row2[j + 1] < row0[j - 1]) /* transposition */ | ||||||
|  | 	        row2[j + 1] = row0[j - 1] + 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tmp = row0; | ||||||
|  | 	row0 = row1; | ||||||
|  | 	row1 = row2; | ||||||
|  | 	row2 = tmp; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     cost = row1[l2]; | ||||||
|  |  | ||||||
|  |     free(row0); | ||||||
|  |     free(row1); | ||||||
|  |     free(row2); | ||||||
|  |  | ||||||
|  |     return cost; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | sl_did_you_mean(SL_cmd *cmds, const char *match) | ||||||
|  | { | ||||||
|  |     int *metrics, best_match = INT_MAX, print = 0; | ||||||
|  |     SL_cmd *c; | ||||||
|  |     size_t n; | ||||||
|  |  | ||||||
|  |     for (n = 0, c = cmds; c->name; c++, n++) | ||||||
|  |         ; | ||||||
|  |     metrics = calloc(n, sizeof(metrics[0])); | ||||||
|  |     if (metrics == NULL) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     for (n = 0; cmds[n].name; n++) { | ||||||
|  |         metrics[n] = osad(match, cmds[n].name); | ||||||
|  | 	if (metrics[n] < best_match) | ||||||
|  | 	    best_match = metrics[n]; | ||||||
|  |     } | ||||||
|  |     if (best_match == INT_MAX) { | ||||||
|  |         free(metrics); | ||||||
|  |         fprintf(stderr, "What kind of command is %s", match); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fprintf(stderr, "%s is not a known command, did you mean:", match); | ||||||
|  |     for (n = 0; cmds[n].name; n++) { | ||||||
|  |       if (metrics[n] == best_match) { | ||||||
|  | 	  fprintf(stderr, "%s %s", print ? "," : "", cmds[n].name); | ||||||
|  | 	  print = 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     fprintf(stderr, ".\n"); | ||||||
|  |  | ||||||
|  |     free(metrics); | ||||||
|  |  | ||||||
|  |     return; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -61,6 +61,8 @@ int sl_make_argv(char*, int*, char***); | |||||||
| void sl_apropos (SL_cmd *cmd, const char *topic); | void sl_apropos (SL_cmd *cmd, const char *topic); | ||||||
| SL_cmd *sl_match (SL_cmd *cmds, char *cmd, int exactp); | SL_cmd *sl_match (SL_cmd *cmds, char *cmd, int exactp); | ||||||
| void sl_slc_help (SL_cmd *cmds, int argc, char **argv); | void sl_slc_help (SL_cmd *cmds, int argc, char **argv); | ||||||
|  | void sl_did_you_mean(SL_cmd *cmds, const char *match); | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Love Hornquist Astrand
					Love Hornquist Astrand