File src/hashset.c changed (mode: 100644) (index b73f8fd..6e06ee0) |
... |
... |
void *hashset_get(const HashSet * hs, const char *key) |
46 |
46 |
|
|
47 |
47 |
int hashset_contains(const HashSet * hs, const char *key) |
int hashset_contains(const HashSet * hs, const char *key) |
48 |
48 |
{ |
{ |
49 |
|
return (hashset_get(hs, key) != NULL); |
|
|
49 |
|
return (hashset_get(hs, key) != NULL); |
50 |
50 |
} |
} |
51 |
51 |
|
|
52 |
52 |
int hashset_put(HashSet *hs, const char *key, void *value) |
int hashset_put(HashSet *hs, const char *key, void *value) |
|
... |
... |
int hashset_put(HashSet *hs, const char *key, void *value) |
74 |
74 |
|
|
75 |
75 |
int hashset_add(HashSet * hs, const char *key) |
int hashset_add(HashSet * hs, const char *key) |
76 |
76 |
{ |
{ |
77 |
|
return hashset_put(hs, key, "nil"); |
|
|
77 |
|
return hashset_put(hs, key, "nil"); |
78 |
78 |
} |
} |
79 |
79 |
|
|
80 |
80 |
int hashset_size(const HashSet *hs) |
int hashset_size(const HashSet *hs) |
|
... |
... |
void hashset_stat(const HashSet *hs) |
95 |
95 |
|
|
96 |
96 |
char** hashset_keys(const HashSet *hs) |
char** hashset_keys(const HashSet *hs) |
97 |
97 |
{ |
{ |
98 |
|
if(hs->currentSize) { |
|
99 |
|
char **result=malloc(sizeof(char*) * hs->currentSize); |
|
100 |
|
int i=0, j=0; |
|
101 |
|
struct HashSetNode *p; |
|
102 |
|
for(i=0; i<HASH_MAP_SIZE; i++) { |
|
103 |
|
p=hs->lists[i]; |
|
104 |
|
while(p && p->next) { |
|
105 |
|
result[j++]=hstr_strdup(p->key); |
|
106 |
|
p=p->next; |
|
107 |
|
} |
|
108 |
|
if(p) { |
|
109 |
|
result[j++]=hstr_strdup(p->key); |
|
110 |
|
} |
|
111 |
|
} |
|
112 |
|
return result; |
|
113 |
|
} else { |
|
114 |
|
return NULL; |
|
115 |
|
} |
|
|
98 |
|
if(hs->currentSize) { |
|
99 |
|
char **result=malloc(sizeof(char*) * hs->currentSize); |
|
100 |
|
int i=0, j=0; |
|
101 |
|
struct HashSetNode *p; |
|
102 |
|
for(i=0; i<HASH_MAP_SIZE; i++) { |
|
103 |
|
p=hs->lists[i]; |
|
104 |
|
while(p && p->next) { |
|
105 |
|
result[j++]=hstr_strdup(p->key); |
|
106 |
|
p=p->next; |
|
107 |
|
} |
|
108 |
|
if(p) { |
|
109 |
|
result[j++]=hstr_strdup(p->key); |
|
110 |
|
} |
|
111 |
|
} |
|
112 |
|
return result; |
|
113 |
|
} else { |
|
114 |
|
return NULL; |
|
115 |
|
} |
116 |
116 |
} |
} |
117 |
117 |
|
|
118 |
118 |
void hashset_destroy(HashSet *hs, const bool freeValues) |
void hashset_destroy(HashSet *hs, const bool freeValues) |
119 |
119 |
{ |
{ |
120 |
|
// only hashset keys (and possibly values) are freed - caller must free hashset itself |
|
121 |
|
if(hs && hs->currentSize) { |
|
122 |
|
int i=0; |
|
123 |
|
struct HashSetNode *p, *pp; |
|
124 |
|
for(i=0; i<HASH_MAP_SIZE; i++) { |
|
125 |
|
p=hs->lists[i]; |
|
126 |
|
while(p && p->next) { |
|
127 |
|
if(p->key) { |
|
128 |
|
free(p->key); |
|
129 |
|
if(freeValues && p->value) free(p->value); |
|
130 |
|
} |
|
131 |
|
pp=p; |
|
132 |
|
p=p->next; |
|
133 |
|
free(pp); |
|
134 |
|
} |
|
135 |
|
if(p && p->key) { |
|
136 |
|
free(p->key); |
|
137 |
|
if(freeValues && p->value) free(p->value); |
|
138 |
|
free(p); |
|
139 |
|
} |
|
140 |
|
} |
|
141 |
|
} |
|
|
120 |
|
// only hashset keys (and possibly values) are freed - caller must free hashset itself |
|
121 |
|
if(hs && hs->currentSize) { |
|
122 |
|
int i=0; |
|
123 |
|
struct HashSetNode *p, *pp; |
|
124 |
|
for(i=0; i<HASH_MAP_SIZE; i++) { |
|
125 |
|
p=hs->lists[i]; |
|
126 |
|
while(p && p->next) { |
|
127 |
|
if(p->key) { |
|
128 |
|
free(p->key); |
|
129 |
|
if(freeValues && p->value) free(p->value); |
|
130 |
|
} |
|
131 |
|
pp=p; |
|
132 |
|
p=p->next; |
|
133 |
|
free(pp); |
|
134 |
|
} |
|
135 |
|
if(p && p->key) { |
|
136 |
|
free(p->key); |
|
137 |
|
if(freeValues && p->value) free(p->value); |
|
138 |
|
free(p); |
|
139 |
|
} |
|
140 |
|
} |
|
141 |
|
} |
142 |
142 |
} |
} |
File src/hstr_favorites.c changed (mode: 100644) (index 77055c7..be966cf) |
18 |
18 |
|
|
19 |
19 |
void favorites_init(FavoriteItems *favorites) |
void favorites_init(FavoriteItems *favorites) |
20 |
20 |
{ |
{ |
21 |
|
favorites->items=NULL; |
|
22 |
|
favorites->count=0; |
|
23 |
|
favorites->loaded=false; |
|
24 |
|
favorites->set=malloc(sizeof(HashSet)); |
|
|
21 |
|
favorites->items=NULL; |
|
22 |
|
favorites->count=0; |
|
23 |
|
favorites->loaded=false; |
|
24 |
|
favorites->set=malloc(sizeof(HashSet)); |
25 |
25 |
} |
} |
26 |
26 |
|
|
27 |
27 |
void favorites_show(FavoriteItems *favorites) |
void favorites_show(FavoriteItems *favorites) |
28 |
28 |
{ |
{ |
29 |
|
printf("\n\nFavorites (%d):", favorites->count); |
|
30 |
|
if(favorites->count) { |
|
31 |
|
int i; |
|
32 |
|
for(i=0;i<favorites->count;i++) { |
|
33 |
|
printf("\n%s",favorites->items[i]); |
|
34 |
|
} |
|
35 |
|
} |
|
36 |
|
printf("\n"); |
|
|
29 |
|
printf("\n\nFavorites (%d):", favorites->count); |
|
30 |
|
if(favorites->count) { |
|
31 |
|
int i; |
|
32 |
|
for(i=0;i<favorites->count;i++) { |
|
33 |
|
printf("\n%s",favorites->items[i]); |
|
34 |
|
} |
|
35 |
|
} |
|
36 |
|
printf("\n"); |
37 |
37 |
} |
} |
38 |
38 |
|
|
39 |
39 |
char* favorites_get_filename() |
char* favorites_get_filename() |
40 |
40 |
{ |
{ |
41 |
|
char *home = getenv(ENV_VAR_HOME); |
|
42 |
|
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_RC) + 1); |
|
43 |
|
strcpy(fileName, home); |
|
44 |
|
strcat(fileName, "/"); |
|
45 |
|
strcat(fileName, FILE_HH_RC); |
|
46 |
|
return fileName; |
|
|
41 |
|
char *home = getenv(ENV_VAR_HOME); |
|
42 |
|
char *fileName = (char*) malloc(strlen(home) + 1 + strlen(FILE_HH_RC) + 1); |
|
43 |
|
strcpy(fileName, home); |
|
44 |
|
strcat(fileName, "/"); |
|
45 |
|
strcat(fileName, FILE_HH_RC); |
|
46 |
|
return fileName; |
47 |
47 |
} |
} |
48 |
48 |
|
|
49 |
49 |
void favorites_get(FavoriteItems *favorites) |
void favorites_get(FavoriteItems *favorites) |
50 |
50 |
{ |
{ |
51 |
|
if(!favorites->loaded) { |
|
52 |
|
char* fileName = favorites_get_filename(); |
|
53 |
|
char *file_contents=NULL; |
|
54 |
|
if(access(fileName, F_OK) != -1) { |
|
55 |
|
long input_file_size; |
|
56 |
|
|
|
57 |
|
FILE *input_file = fopen(fileName, "rb"); |
|
58 |
|
fseek(input_file, 0, SEEK_END); |
|
59 |
|
input_file_size = ftell(input_file); |
|
60 |
|
rewind(input_file); |
|
61 |
|
file_contents = malloc((input_file_size + 1) * (sizeof(char))); |
|
62 |
|
if(fread(file_contents, sizeof(char), input_file_size, input_file)==-1) { |
|
63 |
|
exit(EXIT_FAILURE); |
|
64 |
|
} |
|
65 |
|
fclose(input_file); |
|
66 |
|
file_contents[input_file_size] = 0; |
|
67 |
|
|
|
68 |
|
if(file_contents && strlen(file_contents)) { |
|
69 |
|
favorites->count = 0; |
|
70 |
|
char *p=strchr(file_contents,'\n'); |
|
71 |
|
while (p!=NULL) { |
|
72 |
|
favorites->count++; |
|
73 |
|
p=strchr(p+1,'\n'); |
|
74 |
|
} |
|
75 |
|
|
|
76 |
|
favorites->items = malloc(sizeof(char*) * favorites->count); |
|
77 |
|
favorites->count=0; |
|
78 |
|
char *pb=file_contents, *pe, *s; |
|
79 |
|
pe=strchr(file_contents, '\n'); |
|
80 |
|
HashSet set; |
|
81 |
|
hashset_init(&set); |
|
82 |
|
while(pe!=NULL) { |
|
83 |
|
*pe=0; |
|
84 |
|
if(!hashset_contains(&set,pb)) { |
|
85 |
|
s=hstr_strdup(pb); |
|
86 |
|
favorites->items[favorites->count++]=s; |
|
87 |
|
hashset_add(&set,s); |
|
88 |
|
} |
|
89 |
|
pb=pe+1; |
|
90 |
|
pe=strchr(pb, '\n'); |
|
91 |
|
} |
|
92 |
|
free(file_contents); |
|
93 |
|
} |
|
94 |
|
} else { |
|
95 |
|
// favorites file not found > favorites don't exist yet |
|
96 |
|
favorites->loaded=true; |
|
97 |
|
return; |
|
98 |
|
} |
|
99 |
|
free(fileName); |
|
100 |
|
} |
|
|
51 |
|
if(!favorites->loaded) { |
|
52 |
|
char* fileName = favorites_get_filename(); |
|
53 |
|
char *file_contents=NULL; |
|
54 |
|
if(access(fileName, F_OK) != -1) { |
|
55 |
|
long input_file_size; |
|
56 |
|
|
|
57 |
|
FILE *input_file = fopen(fileName, "rb"); |
|
58 |
|
fseek(input_file, 0, SEEK_END); |
|
59 |
|
input_file_size = ftell(input_file); |
|
60 |
|
rewind(input_file); |
|
61 |
|
file_contents = malloc((input_file_size + 1) * (sizeof(char))); |
|
62 |
|
if(fread(file_contents, sizeof(char), input_file_size, input_file)==-1) { |
|
63 |
|
exit(EXIT_FAILURE); |
|
64 |
|
} |
|
65 |
|
fclose(input_file); |
|
66 |
|
file_contents[input_file_size] = 0; |
|
67 |
|
|
|
68 |
|
if(file_contents && strlen(file_contents)) { |
|
69 |
|
favorites->count = 0; |
|
70 |
|
char *p=strchr(file_contents,'\n'); |
|
71 |
|
while (p!=NULL) { |
|
72 |
|
favorites->count++; |
|
73 |
|
p=strchr(p+1,'\n'); |
|
74 |
|
} |
|
75 |
|
|
|
76 |
|
favorites->items = malloc(sizeof(char*) * favorites->count); |
|
77 |
|
favorites->count=0; |
|
78 |
|
char *pb=file_contents, *pe, *s; |
|
79 |
|
pe=strchr(file_contents, '\n'); |
|
80 |
|
HashSet set; |
|
81 |
|
hashset_init(&set); |
|
82 |
|
while(pe!=NULL) { |
|
83 |
|
*pe=0; |
|
84 |
|
if(!hashset_contains(&set,pb)) { |
|
85 |
|
s=hstr_strdup(pb); |
|
86 |
|
favorites->items[favorites->count++]=s; |
|
87 |
|
hashset_add(&set,s); |
|
88 |
|
} |
|
89 |
|
pb=pe+1; |
|
90 |
|
pe=strchr(pb, '\n'); |
|
91 |
|
} |
|
92 |
|
free(file_contents); |
|
93 |
|
} |
|
94 |
|
} else { |
|
95 |
|
// favorites file not found > favorites don't exist yet |
|
96 |
|
favorites->loaded=true; |
|
97 |
|
return; |
|
98 |
|
} |
|
99 |
|
free(fileName); |
|
100 |
|
} |
101 |
101 |
} |
} |
102 |
102 |
|
|
103 |
103 |
void favorites_save(FavoriteItems *favorites) |
void favorites_save(FavoriteItems *favorites) |
104 |
104 |
{ |
{ |
105 |
|
char *fileName=favorites_get_filename(); |
|
106 |
|
|
|
107 |
|
if(favorites->count) { |
|
108 |
|
FILE *output_file = fopen(fileName, "wb"); |
|
109 |
|
rewind(output_file); |
|
110 |
|
int i; |
|
111 |
|
for(i=0; i<favorites->count; i++) { |
|
112 |
|
if(fwrite(favorites->items[i], sizeof(char), strlen(favorites->items[i]), output_file)==-1) { |
|
113 |
|
exit(EXIT_FAILURE); |
|
114 |
|
} |
|
115 |
|
if(fwrite("\n", sizeof(char), strlen("\n"), output_file)==-1) { |
|
116 |
|
exit(EXIT_FAILURE); |
|
117 |
|
} |
|
118 |
|
} |
|
119 |
|
fclose(output_file); |
|
120 |
|
} else { |
|
121 |
|
if(access(fileName, F_OK) != -1) { |
|
122 |
|
FILE *output_file = fopen(fileName, "wb"); |
|
123 |
|
fclose(output_file); |
|
124 |
|
} |
|
125 |
|
} |
|
126 |
|
free(fileName); |
|
|
105 |
|
char *fileName=favorites_get_filename(); |
|
106 |
|
|
|
107 |
|
if(favorites->count) { |
|
108 |
|
FILE *output_file = fopen(fileName, "wb"); |
|
109 |
|
rewind(output_file); |
|
110 |
|
int i; |
|
111 |
|
for(i=0; i<favorites->count; i++) { |
|
112 |
|
if(fwrite(favorites->items[i], sizeof(char), strlen(favorites->items[i]), output_file)==-1) { |
|
113 |
|
exit(EXIT_FAILURE); |
|
114 |
|
} |
|
115 |
|
if(fwrite("\n", sizeof(char), strlen("\n"), output_file)==-1) { |
|
116 |
|
exit(EXIT_FAILURE); |
|
117 |
|
} |
|
118 |
|
} |
|
119 |
|
fclose(output_file); |
|
120 |
|
} else { |
|
121 |
|
if(access(fileName, F_OK) != -1) { |
|
122 |
|
FILE *output_file = fopen(fileName, "wb"); |
|
123 |
|
fclose(output_file); |
|
124 |
|
} |
|
125 |
|
} |
|
126 |
|
free(fileName); |
127 |
127 |
} |
} |
128 |
128 |
|
|
129 |
129 |
void favorites_add(FavoriteItems *favorites, char *newFavorite) |
void favorites_add(FavoriteItems *favorites, char *newFavorite) |
130 |
130 |
{ |
{ |
131 |
|
if(favorites->count) { |
|
132 |
|
favorites->items=realloc(favorites->items, sizeof(char *) * ++favorites->count); |
|
133 |
|
favorites->items[favorites->count-1]=hstr_strdup(newFavorite); |
|
134 |
|
favorites_choose(favorites, newFavorite); |
|
135 |
|
} else { |
|
136 |
|
favorites->items=malloc(sizeof(char*)); |
|
137 |
|
favorites->items[0]=hstr_strdup(newFavorite); |
|
138 |
|
favorites->count=1; |
|
139 |
|
} |
|
140 |
|
|
|
141 |
|
favorites_save(favorites); |
|
|
131 |
|
if(favorites->count) { |
|
132 |
|
favorites->items=realloc(favorites->items, sizeof(char *) * ++favorites->count); |
|
133 |
|
favorites->items[favorites->count-1]=hstr_strdup(newFavorite); |
|
134 |
|
favorites_choose(favorites, newFavorite); |
|
135 |
|
} else { |
|
136 |
|
favorites->items=malloc(sizeof(char*)); |
|
137 |
|
favorites->items[0]=hstr_strdup(newFavorite); |
|
138 |
|
favorites->count=1; |
|
139 |
|
} |
|
140 |
|
|
|
141 |
|
favorites_save(favorites); |
142 |
142 |
} |
} |
143 |
143 |
|
|
144 |
144 |
void favorites_choose(FavoriteItems *favorites, char *choice) |
void favorites_choose(FavoriteItems *favorites, char *choice) |
145 |
145 |
{ |
{ |
146 |
|
if(favorites->count && choice) { |
|
147 |
|
int r; |
|
148 |
|
char *b=NULL, *next; |
|
149 |
|
for(r=0; r<favorites->count; r++) { |
|
150 |
|
if(!strcmp(favorites->items[r],choice)) { |
|
151 |
|
favorites->items[0]=favorites->items[r]; |
|
152 |
|
if(b) { |
|
153 |
|
favorites->items[r]=b; |
|
154 |
|
} |
|
155 |
|
favorites_save(favorites); |
|
156 |
|
return; |
|
157 |
|
} |
|
158 |
|
next=favorites->items[r]; |
|
159 |
|
favorites->items[r]=b; |
|
160 |
|
b=next; |
|
161 |
|
} |
|
162 |
|
} |
|
|
146 |
|
if(favorites->count && choice) { |
|
147 |
|
int r; |
|
148 |
|
char *b=NULL, *next; |
|
149 |
|
for(r=0; r<favorites->count; r++) { |
|
150 |
|
if(!strcmp(favorites->items[r],choice)) { |
|
151 |
|
favorites->items[0]=favorites->items[r]; |
|
152 |
|
if(b) { |
|
153 |
|
favorites->items[r]=b; |
|
154 |
|
} |
|
155 |
|
favorites_save(favorites); |
|
156 |
|
return; |
|
157 |
|
} |
|
158 |
|
next=favorites->items[r]; |
|
159 |
|
favorites->items[r]=b; |
|
160 |
|
b=next; |
|
161 |
|
} |
|
162 |
|
} |
163 |
163 |
} |
} |
164 |
164 |
|
|
165 |
165 |
bool favorites_remove(FavoriteItems *favorites, char *almostDead) |
bool favorites_remove(FavoriteItems *favorites, char *almostDead) |
166 |
166 |
{ |
{ |
167 |
|
if(favorites->count) { |
|
168 |
|
int r, w, count; |
|
169 |
|
count=favorites->count; |
|
170 |
|
for(r=0, w=0; r<count; r++) { |
|
171 |
|
if(!strcmp(favorites->items[r], almostDead)) { |
|
172 |
|
favorites->count--; |
|
173 |
|
} else { |
|
174 |
|
if(w<r) { |
|
175 |
|
favorites->items[w]=favorites->items[r]; |
|
176 |
|
} |
|
177 |
|
w++; |
|
178 |
|
} |
|
179 |
|
} |
|
180 |
|
favorites_save(favorites); |
|
181 |
|
return true; |
|
182 |
|
} else { |
|
183 |
|
return false; |
|
184 |
|
} |
|
|
167 |
|
if(favorites->count) { |
|
168 |
|
int r, w, count; |
|
169 |
|
count=favorites->count; |
|
170 |
|
for(r=0, w=0; r<count; r++) { |
|
171 |
|
if(!strcmp(favorites->items[r], almostDead)) { |
|
172 |
|
favorites->count--; |
|
173 |
|
} else { |
|
174 |
|
if(w<r) { |
|
175 |
|
favorites->items[w]=favorites->items[r]; |
|
176 |
|
} |
|
177 |
|
w++; |
|
178 |
|
} |
|
179 |
|
} |
|
180 |
|
favorites_save(favorites); |
|
181 |
|
return true; |
|
182 |
|
} else { |
|
183 |
|
return false; |
|
184 |
|
} |
185 |
185 |
} |
} |
186 |
186 |
|
|
187 |
187 |
void favorites_destroy(FavoriteItems *favorites) |
void favorites_destroy(FavoriteItems *favorites) |
188 |
188 |
{ |
{ |
189 |
|
if(favorites) { |
|
190 |
|
int i; |
|
191 |
|
for(i=0; i<favorites->count; i++) { |
|
192 |
|
free(favorites->items[i]); |
|
193 |
|
} |
|
194 |
|
hashset_destroy(favorites->set, false); |
|
195 |
|
free(favorites); |
|
196 |
|
} |
|
|
189 |
|
if(favorites) { |
|
190 |
|
int i; |
|
191 |
|
for(i=0; i<favorites->count; i++) { |
|
192 |
|
free(favorites->items[i]); |
|
193 |
|
} |
|
194 |
|
hashset_destroy(favorites->set, false); |
|
195 |
|
free(favorites); |
|
196 |
|
} |
197 |
197 |
} |
} |
File src/hstr_history.c changed (mode: 100644) (index 35655db..722625f) |
16 |
16 |
#include <assert.h> |
#include <assert.h> |
17 |
17 |
|
|
18 |
18 |
typedef struct { |
typedef struct { |
19 |
|
char *item; |
|
20 |
|
unsigned rank; |
|
|
19 |
|
char *item; |
|
20 |
|
unsigned rank; |
21 |
21 |
} RankedHistoryItem; |
} RankedHistoryItem; |
22 |
22 |
|
|
23 |
23 |
static HistoryItems *prioritizedHistory; |
static HistoryItems *prioritizedHistory; |
24 |
24 |
static bool dirty; |
static bool dirty; |
25 |
25 |
|
|
26 |
26 |
static const char *commandBlacklist[] = { |
static const char *commandBlacklist[] = { |
27 |
|
"ls", "pwd", "cd", "cd ..", "hh", "mc", |
|
28 |
|
"ls ", "pwd ", "cd ", "cd .. ", "hh ", "mc " |
|
|
27 |
|
"ls", "pwd", "cd", "cd ..", "hh", "mc", |
|
28 |
|
"ls ", "pwd ", "cd ", "cd .. ", "hh ", "mc " |
29 |
29 |
}; |
}; |
30 |
30 |
|
|
31 |
31 |
#ifdef DEBUG_RADIX |
#ifdef DEBUG_RADIX |
|
... |
... |
static const char *commandBlacklist[] = { |
35 |
35 |
#endif |
#endif |
36 |
36 |
|
|
37 |
37 |
unsigned history_ranking_function(unsigned rank, int newOccurenceOrder, size_t length) { |
unsigned history_ranking_function(unsigned rank, int newOccurenceOrder, size_t length) { |
38 |
|
long metrics=rank+(log(newOccurenceOrder)*10.0)+length; |
|
39 |
|
// alternative metrics: |
|
40 |
|
// rank+newOccurenceOrder/10+length |
|
41 |
|
assert(metrics<UINT_MAX); |
|
42 |
|
return metrics; |
|
|
38 |
|
long metrics=rank+(log(newOccurenceOrder)*10.0)+length; |
|
39 |
|
// alternative metrics: |
|
40 |
|
// rank+newOccurenceOrder/10+length |
|
41 |
|
assert(metrics<UINT_MAX); |
|
42 |
|
return metrics; |
43 |
43 |
} |
} |
44 |
44 |
|
|
45 |
45 |
char *get_history_file_name() |
char *get_history_file_name() |
46 |
46 |
{ |
{ |
47 |
|
char *historyFile=getenv(ENV_VAR_HISTFILE); |
|
48 |
|
if(!historyFile || strlen(historyFile)==0) { |
|
49 |
|
char *home = getenv(ENV_VAR_HOME); |
|
50 |
|
historyFile = malloc(strlen(home) + 1 + strlen(FILE_DEFAULT_HISTORY) + 1); |
|
51 |
|
strcat(strcat(strcpy(historyFile, home), "/"), FILE_DEFAULT_HISTORY); |
|
52 |
|
} |
|
53 |
|
return historyFile; |
|
|
47 |
|
char *historyFile=getenv(ENV_VAR_HISTFILE); |
|
48 |
|
if(!historyFile || strlen(historyFile)==0) { |
|
49 |
|
char *home = getenv(ENV_VAR_HOME); |
|
50 |
|
historyFile = malloc(strlen(home) + 1 + strlen(FILE_DEFAULT_HISTORY) + 1); |
|
51 |
|
strcat(strcat(strcpy(historyFile, home), "/"), FILE_DEFAULT_HISTORY); |
|
52 |
|
} |
|
53 |
|
return historyFile; |
54 |
54 |
} |
} |
55 |
55 |
|
|
56 |
56 |
void dump_prioritized_history(HistoryItems *ph) |
void dump_prioritized_history(HistoryItems *ph) |
57 |
57 |
{ |
{ |
58 |
|
printf("\n\nPrioritized history:"); |
|
59 |
|
int i; |
|
60 |
|
for(i=0; i<ph->count; i++) { |
|
61 |
|
if(ph->items[i]!=NULL) { |
|
62 |
|
printf("\n%s",ph->items[i]); fflush(stdout); |
|
63 |
|
} else { |
|
64 |
|
printf("\n %d NULL",i); fflush(stdout); |
|
65 |
|
} |
|
66 |
|
} |
|
67 |
|
printf("\n"); fflush(stdout); |
|
|
58 |
|
printf("\n\nPrioritized history:"); |
|
59 |
|
int i; |
|
60 |
|
for(i=0; i<ph->count; i++) { |
|
61 |
|
if(ph->items[i]!=NULL) { |
|
62 |
|
printf("\n%s",ph->items[i]); fflush(stdout); |
|
63 |
|
} else { |
|
64 |
|
printf("\n %d NULL",i); fflush(stdout); |
|
65 |
|
} |
|
66 |
|
} |
|
67 |
|
printf("\n"); fflush(stdout); |
68 |
68 |
} |
} |
69 |
69 |
|
|
70 |
70 |
HistoryItems *get_prioritized_history() |
HistoryItems *get_prioritized_history() |
71 |
71 |
{ |
{ |
72 |
|
using_history(); |
|
73 |
|
|
|
74 |
|
char *historyFile = get_history_file_name(); |
|
75 |
|
if(read_history(historyFile)!=0) { |
|
76 |
|
fprintf(stderr, "\nUnable to read history file from '%s'!\n",historyFile); |
|
77 |
|
exit(EXIT_FAILURE); |
|
78 |
|
} |
|
79 |
|
HISTORY_STATE *historyState=history_get_history_state(); |
|
80 |
|
|
|
81 |
|
if(historyState->length > 0) { |
|
82 |
|
HashSet rankmap; |
|
83 |
|
hashset_init(&rankmap); |
|
84 |
|
|
|
85 |
|
HashSet blacklist; |
|
86 |
|
int i; |
|
87 |
|
hashset_init(&blacklist); |
|
88 |
|
int length=sizeof(commandBlacklist)/sizeof(commandBlacklist[0]); |
|
89 |
|
for(i=0; i<length; i++) { |
|
90 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
91 |
|
} |
|
92 |
|
|
|
93 |
|
RadixSorter rs; |
|
94 |
|
unsigned radixMaxKeyEstimate=historyState->size*1000; |
|
95 |
|
radixsort_init(&rs, (radixMaxKeyEstimate<100000?100000:radixMaxKeyEstimate)); |
|
96 |
|
rs.optFloorAndInsertBigKeys=true; |
|
97 |
|
|
|
98 |
|
RankedHistoryItem *r; |
|
99 |
|
RadixItem *radixItem; |
|
|
72 |
|
using_history(); |
|
73 |
|
|
|
74 |
|
char *historyFile = get_history_file_name(); |
|
75 |
|
if(read_history(historyFile)!=0) { |
|
76 |
|
fprintf(stderr, "\nUnable to read history file from '%s'!\n",historyFile); |
|
77 |
|
exit(EXIT_FAILURE); |
|
78 |
|
} |
|
79 |
|
HISTORY_STATE *historyState=history_get_history_state(); |
|
80 |
|
|
|
81 |
|
if(historyState->length > 0) { |
|
82 |
|
HashSet rankmap; |
|
83 |
|
hashset_init(&rankmap); |
|
84 |
|
|
|
85 |
|
HashSet blacklist; |
|
86 |
|
int i; |
|
87 |
|
hashset_init(&blacklist); |
|
88 |
|
int length=sizeof(commandBlacklist)/sizeof(commandBlacklist[0]); |
|
89 |
|
for(i=0; i<length; i++) { |
|
90 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
91 |
|
} |
|
92 |
|
|
|
93 |
|
RadixSorter rs; |
|
94 |
|
unsigned radixMaxKeyEstimate=historyState->size*1000; |
|
95 |
|
radixsort_init(&rs, (radixMaxKeyEstimate<100000?100000:radixMaxKeyEstimate)); |
|
96 |
|
rs.optFloorAndInsertBigKeys=true; |
|
97 |
|
|
|
98 |
|
RankedHistoryItem *r; |
|
99 |
|
RadixItem *radixItem; |
100 |
100 |
HIST_ENTRY **historyList=history_list(); |
HIST_ENTRY **historyList=history_list(); |
101 |
101 |
char **rawHistory=malloc(sizeof(char*) * historyState->length); |
char **rawHistory=malloc(sizeof(char*) * historyState->length); |
102 |
102 |
int rawOffset=historyState->length-1; |
int rawOffset=historyState->length-1; |
103 |
|
char *line; |
|
104 |
|
for(i=0; i<historyState->length; i++, rawOffset--) { |
|
105 |
|
line=historyList[i]->line; |
|
106 |
|
rawHistory[rawOffset]=line; |
|
107 |
|
if(hashset_contains(&blacklist, line)) { |
|
108 |
|
continue; |
|
109 |
|
} |
|
110 |
|
if((r=hashset_get(&rankmap, line))==NULL) { |
|
111 |
|
r=malloc(sizeof(RankedHistoryItem)); |
|
112 |
|
r->rank=history_ranking_function(0, i, strlen(line)); |
|
113 |
|
r->item=historyList[i]->line; |
|
114 |
|
|
|
115 |
|
hashset_put(&rankmap, line, r); |
|
116 |
|
|
|
117 |
|
radixItem=malloc(sizeof(RadixItem)); |
|
118 |
|
radixItem->key=r->rank; |
|
119 |
|
radixItem->data=r; |
|
120 |
|
radixItem->next=NULL; |
|
121 |
|
radixsort_add(&rs, radixItem); |
|
122 |
|
} else { |
|
123 |
|
radixItem=radix_cut(&rs, r->rank, r); |
|
124 |
|
|
|
125 |
|
assert(radixItem); |
|
126 |
|
|
|
127 |
|
if(radixItem) { |
|
128 |
|
r->rank=history_ranking_function(r->rank, i, strlen(line)); |
|
129 |
|
radixItem->key=r->rank; |
|
130 |
|
radixsort_add(&rs, radixItem); |
|
131 |
|
} |
|
132 |
|
} |
|
133 |
|
} |
|
134 |
|
|
|
135 |
|
DEBUG_RADIXSORT(); |
|
136 |
|
|
|
137 |
|
RadixItem **prioritizedRadix=radixsort_dump(&rs); |
|
138 |
|
prioritizedHistory=malloc(sizeof(HistoryItems)); |
|
139 |
|
prioritizedHistory->count=rs.size; |
|
140 |
|
prioritizedHistory->rawCount=historyState->length; |
|
141 |
|
prioritizedHistory->items=malloc(rs.size * sizeof(char*)); |
|
142 |
|
prioritizedHistory->raw=rawHistory; |
|
143 |
|
for(i=0; i<rs.size; i++) { |
|
144 |
|
if(prioritizedRadix[i]->data) { |
|
145 |
|
prioritizedHistory->items[i]=((RankedHistoryItem *)(prioritizedRadix[i]->data))->item; |
|
146 |
|
} |
|
147 |
|
free(prioritizedRadix[i]->data); |
|
148 |
|
free(prioritizedRadix[i]); |
|
149 |
|
} |
|
150 |
|
|
|
151 |
|
radixsort_destroy(&rs); |
|
152 |
|
// TODO rankmap (?) and blacklist (?) to be destroyed |
|
153 |
|
|
|
154 |
|
return prioritizedHistory; |
|
155 |
|
} else { |
|
156 |
|
return NULL; |
|
157 |
|
} |
|
|
103 |
|
char *line; |
|
104 |
|
for(i=0; i<historyState->length; i++, rawOffset--) { |
|
105 |
|
line=historyList[i]->line; |
|
106 |
|
rawHistory[rawOffset]=line; |
|
107 |
|
if(hashset_contains(&blacklist, line)) { |
|
108 |
|
continue; |
|
109 |
|
} |
|
110 |
|
if((r=hashset_get(&rankmap, line))==NULL) { |
|
111 |
|
r=malloc(sizeof(RankedHistoryItem)); |
|
112 |
|
r->rank=history_ranking_function(0, i, strlen(line)); |
|
113 |
|
r->item=historyList[i]->line; |
|
114 |
|
|
|
115 |
|
hashset_put(&rankmap, line, r); |
|
116 |
|
|
|
117 |
|
radixItem=malloc(sizeof(RadixItem)); |
|
118 |
|
radixItem->key=r->rank; |
|
119 |
|
radixItem->data=r; |
|
120 |
|
radixItem->next=NULL; |
|
121 |
|
radixsort_add(&rs, radixItem); |
|
122 |
|
} else { |
|
123 |
|
radixItem=radix_cut(&rs, r->rank, r); |
|
124 |
|
|
|
125 |
|
assert(radixItem); |
|
126 |
|
|
|
127 |
|
if(radixItem) { |
|
128 |
|
r->rank=history_ranking_function(r->rank, i, strlen(line)); |
|
129 |
|
radixItem->key=r->rank; |
|
130 |
|
radixsort_add(&rs, radixItem); |
|
131 |
|
} |
|
132 |
|
} |
|
133 |
|
} |
|
134 |
|
|
|
135 |
|
DEBUG_RADIXSORT(); |
|
136 |
|
|
|
137 |
|
RadixItem **prioritizedRadix=radixsort_dump(&rs); |
|
138 |
|
prioritizedHistory=malloc(sizeof(HistoryItems)); |
|
139 |
|
prioritizedHistory->count=rs.size; |
|
140 |
|
prioritizedHistory->rawCount=historyState->length; |
|
141 |
|
prioritizedHistory->items=malloc(rs.size * sizeof(char*)); |
|
142 |
|
prioritizedHistory->raw=rawHistory; |
|
143 |
|
for(i=0; i<rs.size; i++) { |
|
144 |
|
if(prioritizedRadix[i]->data) { |
|
145 |
|
prioritizedHistory->items[i]=((RankedHistoryItem *)(prioritizedRadix[i]->data))->item; |
|
146 |
|
} |
|
147 |
|
free(prioritizedRadix[i]->data); |
|
148 |
|
free(prioritizedRadix[i]); |
|
149 |
|
} |
|
150 |
|
|
|
151 |
|
radixsort_destroy(&rs); |
|
152 |
|
// TODO rankmap (?) and blacklist (?) to be destroyed |
|
153 |
|
|
|
154 |
|
return prioritizedHistory; |
|
155 |
|
} else { |
|
156 |
|
return NULL; |
|
157 |
|
} |
158 |
158 |
} |
} |
159 |
159 |
|
|
160 |
160 |
void free_prioritized_history() |
void free_prioritized_history() |
161 |
161 |
{ |
{ |
162 |
|
free(prioritizedHistory->items); |
|
163 |
|
free(prioritizedHistory); |
|
|
162 |
|
free(prioritizedHistory->items); |
|
163 |
|
free(prioritizedHistory); |
164 |
164 |
} |
} |
165 |
165 |
|
|
166 |
166 |
void history_mgmt_open() |
void history_mgmt_open() |
167 |
167 |
{ |
{ |
168 |
|
dirty=false; |
|
|
168 |
|
dirty=false; |
169 |
169 |
} |
} |
170 |
170 |
|
|
171 |
171 |
void history_clear_dirty() |
void history_clear_dirty() |
172 |
172 |
{ |
{ |
173 |
|
dirty=false; |
|
|
173 |
|
dirty=false; |
174 |
174 |
} |
} |
175 |
175 |
|
|
176 |
176 |
int history_mgmt_remove(char *cmd) |
int history_mgmt_remove(char *cmd) |
177 |
177 |
{ |
{ |
178 |
|
int offset=history_search_pos(cmd, 0, 0), occurences=0; |
|
179 |
|
char *l; |
|
180 |
|
HISTORY_STATE *historyState=history_get_history_state(); |
|
181 |
|
while(offset>=0) { |
|
182 |
|
l=historyState->entries[offset]->line; |
|
183 |
|
if(offset<historyState->length && !strcmp(cmd, l)) { |
|
184 |
|
occurences++; |
|
185 |
|
free_history_entry(remove_history(offset)); |
|
186 |
|
} |
|
187 |
|
offset=history_search_pos(cmd, 0, ++offset); |
|
188 |
|
} |
|
189 |
|
if(occurences) { |
|
190 |
|
write_history(get_history_file_name()); |
|
191 |
|
dirty=true; |
|
192 |
|
} |
|
193 |
|
return occurences; |
|
|
178 |
|
int offset=history_search_pos(cmd, 0, 0), occurences=0; |
|
179 |
|
char *l; |
|
180 |
|
HISTORY_STATE *historyState=history_get_history_state(); |
|
181 |
|
while(offset>=0) { |
|
182 |
|
l=historyState->entries[offset]->line; |
|
183 |
|
if(offset<historyState->length && !strcmp(cmd, l)) { |
|
184 |
|
occurences++; |
|
185 |
|
free_history_entry(remove_history(offset)); |
|
186 |
|
} |
|
187 |
|
offset=history_search_pos(cmd, 0, ++offset); |
|
188 |
|
} |
|
189 |
|
if(occurences) { |
|
190 |
|
write_history(get_history_file_name()); |
|
191 |
|
dirty=true; |
|
192 |
|
} |
|
193 |
|
return occurences; |
194 |
194 |
} |
} |
195 |
195 |
|
|
196 |
196 |
void history_mgmt_flush() |
void history_mgmt_flush() |
197 |
197 |
{ |
{ |
198 |
|
if(dirty) { |
|
199 |
|
fill_terminal_input("history -r\n", false); |
|
200 |
|
} |
|
|
198 |
|
if(dirty) { |
|
199 |
|
fill_terminal_input("history -r\n", false); |
|
200 |
|
} |
201 |
201 |
} |
} |
File src/hstr_regexp.c changed (mode: 100644) (index 06e9029..dc6c59d) |
15 |
15 |
|
|
16 |
16 |
void hstr_regexp_init(HstrRegexp *hstrRegexp) |
void hstr_regexp_init(HstrRegexp *hstrRegexp) |
17 |
17 |
{ |
{ |
18 |
|
hashset_init(&hstrRegexp->cache); |
|
|
18 |
|
hashset_init(&hstrRegexp->cache); |
19 |
19 |
} |
} |
20 |
20 |
|
|
21 |
21 |
bool hstr_regexp_match( |
bool hstr_regexp_match( |
22 |
|
HstrRegexp *hstrRegexp, |
|
23 |
|
const char *regexp, |
|
24 |
|
const char *text, |
|
25 |
|
regmatch_t *match, |
|
26 |
|
char *errorMessage, |
|
27 |
|
const size_t errorMessageSize) |
|
|
22 |
|
HstrRegexp *hstrRegexp, |
|
23 |
|
const char *regexp, |
|
24 |
|
const char *text, |
|
25 |
|
regmatch_t *match, |
|
26 |
|
char *errorMessage, |
|
27 |
|
const size_t errorMessageSize) |
28 |
28 |
{ |
{ |
29 |
|
regex_t* compiled; |
|
30 |
|
if(hashset_contains(&hstrRegexp->cache,regexp)) { |
|
31 |
|
compiled=hashset_get(&hstrRegexp->cache, regexp); |
|
32 |
|
} else { |
|
33 |
|
compiled=malloc(sizeof(regex_t)); |
|
34 |
|
int compilationFlags=(hstrRegexp->caseSensitive?0:REG_ICASE); |
|
35 |
|
int compilationStatus=regcomp(compiled, regexp, compilationFlags); |
|
36 |
|
if(!compilationStatus) { |
|
37 |
|
hashset_put(&hstrRegexp->cache, hstr_strdup(regexp), compiled); |
|
38 |
|
} else { |
|
39 |
|
regerror(compilationStatus, compiled, errorMessage, errorMessageSize); |
|
40 |
|
free(compiled); |
|
41 |
|
return false; |
|
42 |
|
} |
|
43 |
|
} |
|
|
29 |
|
regex_t* compiled; |
|
30 |
|
if(hashset_contains(&hstrRegexp->cache,regexp)) { |
|
31 |
|
compiled=hashset_get(&hstrRegexp->cache, regexp); |
|
32 |
|
} else { |
|
33 |
|
compiled=malloc(sizeof(regex_t)); |
|
34 |
|
int compilationFlags=(hstrRegexp->caseSensitive?0:REG_ICASE); |
|
35 |
|
int compilationStatus=regcomp(compiled, regexp, compilationFlags); |
|
36 |
|
if(!compilationStatus) { |
|
37 |
|
hashset_put(&hstrRegexp->cache, hstr_strdup(regexp), compiled); |
|
38 |
|
} else { |
|
39 |
|
regerror(compilationStatus, compiled, errorMessage, errorMessageSize); |
|
40 |
|
free(compiled); |
|
41 |
|
return false; |
|
42 |
|
} |
|
43 |
|
} |
44 |
44 |
|
|
45 |
|
int matches=REGEXP_MATCH_BUFFER_SIZE; |
|
46 |
|
regmatch_t matchPtr[REGEXP_MATCH_BUFFER_SIZE]; |
|
47 |
|
int matchingFlags=0; |
|
48 |
|
int matchingStatus=regexec(compiled, text, matches, matchPtr, matchingFlags); |
|
49 |
|
if(!matchingStatus) { |
|
50 |
|
if(matchPtr[0].rm_so != -1) { |
|
51 |
|
match->rm_so=matchPtr[0].rm_so; |
|
52 |
|
match->rm_eo=matchPtr[0].rm_eo; |
|
53 |
|
return true; |
|
54 |
|
} |
|
55 |
|
} |
|
56 |
|
return false; |
|
|
45 |
|
int matches=REGEXP_MATCH_BUFFER_SIZE; |
|
46 |
|
regmatch_t matchPtr[REGEXP_MATCH_BUFFER_SIZE]; |
|
47 |
|
int matchingFlags=0; |
|
48 |
|
int matchingStatus=regexec(compiled, text, matches, matchPtr, matchingFlags); |
|
49 |
|
if(!matchingStatus) { |
|
50 |
|
if(matchPtr[0].rm_so != -1) { |
|
51 |
|
match->rm_so=matchPtr[0].rm_so; |
|
52 |
|
match->rm_eo=matchPtr[0].rm_eo; |
|
53 |
|
return true; |
|
54 |
|
} |
|
55 |
|
} |
|
56 |
|
return false; |
57 |
57 |
} |
} |
58 |
58 |
|
|
59 |
59 |
void hstr_regexp_destroy(HstrRegexp *hstrRegexp) |
void hstr_regexp_destroy(HstrRegexp *hstrRegexp) |
60 |
60 |
{ |
{ |
61 |
|
hashset_destroy(&hstrRegexp->cache, true); |
|
|
61 |
|
hashset_destroy(&hstrRegexp->cache, true); |
62 |
62 |
} |
} |
File src/hstr_utils.c changed (mode: 100644) (index 720663b..57b7621) |
... |
... |
char *hstr_strdup(const char * s) |
25 |
25 |
// wide char aware strlen() |
// wide char aware strlen() |
26 |
26 |
int hstr_strlen(const char *s) |
int hstr_strlen(const char *s) |
27 |
27 |
{ |
{ |
28 |
|
if(s) { |
|
29 |
|
int result=0; |
|
30 |
|
bool isHighBitSet=false; |
|
31 |
|
int i=0; |
|
32 |
|
while(s[i]) { |
|
33 |
|
if(1<<7 & s[i]) { |
|
34 |
|
if(isHighBitSet) { |
|
35 |
|
isHighBitSet=false; |
|
36 |
|
result++; |
|
37 |
|
} else { |
|
38 |
|
isHighBitSet=true; |
|
39 |
|
} |
|
40 |
|
} else { |
|
41 |
|
result++; |
|
42 |
|
} |
|
43 |
|
i++; |
|
44 |
|
} |
|
45 |
|
return result; |
|
46 |
|
} else { |
|
47 |
|
return 0; |
|
48 |
|
} |
|
|
28 |
|
if(s) { |
|
29 |
|
int result=0; |
|
30 |
|
bool isHighBitSet=false; |
|
31 |
|
int i=0; |
|
32 |
|
while(s[i]) { |
|
33 |
|
if(1<<7 & s[i]) { |
|
34 |
|
if(isHighBitSet) { |
|
35 |
|
isHighBitSet=false; |
|
36 |
|
result++; |
|
37 |
|
} else { |
|
38 |
|
isHighBitSet=true; |
|
39 |
|
} |
|
40 |
|
} else { |
|
41 |
|
result++; |
|
42 |
|
} |
|
43 |
|
i++; |
|
44 |
|
} |
|
45 |
|
return result; |
|
46 |
|
} else { |
|
47 |
|
return 0; |
|
48 |
|
} |
49 |
49 |
} |
} |
50 |
50 |
|
|
51 |
51 |
void hstr_chop(char *s) |
void hstr_chop(char *s) |
52 |
52 |
{ |
{ |
53 |
|
if(s) { |
|
54 |
|
int i=strlen(s); |
|
55 |
|
if(i) { |
|
56 |
|
if(1<<7 & s[i-1]) { |
|
57 |
|
s[i-2]=0; |
|
58 |
|
} else { |
|
59 |
|
s[i-1]=0; |
|
60 |
|
} |
|
61 |
|
} |
|
62 |
|
} |
|
|
53 |
|
if(s) { |
|
54 |
|
int i=strlen(s); |
|
55 |
|
if(i) { |
|
56 |
|
if(1<<7 & s[i-1]) { |
|
57 |
|
s[i-2]=0; |
|
58 |
|
} else { |
|
59 |
|
s[i-1]=0; |
|
60 |
|
} |
|
61 |
|
} |
|
62 |
|
} |
63 |
63 |
} |
} |
64 |
64 |
|
|
65 |
65 |
void tiocsti() |
void tiocsti() |
66 |
66 |
{ |
{ |
67 |
|
char buf[] = DEFAULT_COMMAND; |
|
68 |
|
int i; |
|
69 |
|
for (i = 0; i < sizeof buf - 1; i++) { |
|
70 |
|
ioctl(0, TIOCSTI, &buf[i]); |
|
71 |
|
} |
|
|
67 |
|
char buf[] = DEFAULT_COMMAND; |
|
68 |
|
int i; |
|
69 |
|
for (i = 0; i < sizeof buf - 1; i++) { |
|
70 |
|
ioctl(0, TIOCSTI, &buf[i]); |
|
71 |
|
} |
72 |
72 |
} |
} |
73 |
73 |
|
|
74 |
74 |
void fill_terminal_input(char *cmd, bool padding) |
void fill_terminal_input(char *cmd, bool padding) |
75 |
75 |
{ |
{ |
76 |
|
if(cmd && strlen(cmd)>0) { |
|
77 |
|
size_t size = strlen(cmd); |
|
78 |
|
unsigned i; |
|
79 |
|
char *c; |
|
80 |
|
for (i = 0; i < size; i++) { |
|
81 |
|
// terminal I/O control, simulate terminal input |
|
82 |
|
c=(cmd+i); |
|
83 |
|
ioctl(0, TIOCSTI, c); |
|
84 |
|
} |
|
85 |
|
// echo, but don't flush to terminal |
|
86 |
|
if(padding) printf("\n"); |
|
87 |
|
} |
|
|
76 |
|
if(cmd && strlen(cmd)>0) { |
|
77 |
|
size_t size = strlen(cmd); |
|
78 |
|
unsigned i; |
|
79 |
|
char *c; |
|
80 |
|
for (i = 0; i < size; i++) { |
|
81 |
|
// terminal I/O control, simulate terminal input |
|
82 |
|
c=(cmd+i); |
|
83 |
|
ioctl(0, TIOCSTI, c); |
|
84 |
|
} |
|
85 |
|
// echo, but don't flush to terminal |
|
86 |
|
if(padding) printf("\n"); |
|
87 |
|
} |
88 |
88 |
} |
} |
89 |
89 |
|
|
90 |
90 |
void reverse_char_pointer_array(char **array, unsigned length) |
void reverse_char_pointer_array(char **array, unsigned length) |
91 |
91 |
{ |
{ |
92 |
|
char *temp; |
|
93 |
|
unsigned i; |
|
|
92 |
|
char *temp; |
|
93 |
|
unsigned i; |
94 |
94 |
for (i=0; i<length/2; i++) { |
for (i=0; i<length/2; i++) { |
95 |
95 |
temp = array[i]; |
temp = array[i]; |
96 |
96 |
array[i] = array[length-i-1]; |
array[i] = array[length-i-1]; |
|
... |
... |
void reverse_char_pointer_array(char **array, unsigned length) |
101 |
101 |
void get_hostname(int bufferSize, char *buffer) |
void get_hostname(int bufferSize, char *buffer) |
102 |
102 |
{ |
{ |
103 |
103 |
char *b=buffer; |
char *b=buffer; |
104 |
|
if(access(PROC_HOSTNAME, F_OK) != -1) { |
|
105 |
|
FILE *file = fopen(PROC_HOSTNAME, "r"); |
|
106 |
|
b=fgets(buffer, bufferSize, file); |
|
107 |
|
fclose(file); |
|
108 |
|
if(b) { |
|
109 |
|
b[strlen(b)-1]=0; |
|
110 |
|
return; |
|
111 |
|
} |
|
112 |
|
} |
|
|
104 |
|
if(access(PROC_HOSTNAME, F_OK) != -1) { |
|
105 |
|
FILE *file = fopen(PROC_HOSTNAME, "r"); |
|
106 |
|
b=fgets(buffer, bufferSize, file); |
|
107 |
|
fclose(file); |
|
108 |
|
if(b) { |
|
109 |
|
b[strlen(b)-1]=0; |
|
110 |
|
return; |
|
111 |
|
} |
|
112 |
|
} |
113 |
113 |
strcpy(buffer,"localhost"); |
strcpy(buffer,"localhost"); |
114 |
114 |
} |
} |
115 |
115 |
|
|
116 |
116 |
void toggle_case(char *str, bool lowercase) { |
void toggle_case(char *str, bool lowercase) { |
117 |
|
if(str && strlen(str)>0) { |
|
118 |
|
int i; |
|
119 |
|
for(i = 0; str[i]; i++){ |
|
120 |
|
if(lowercase) { |
|
121 |
|
str[i] = tolower(str[i]); |
|
122 |
|
} else { |
|
123 |
|
str[i] = toupper(str[i]); |
|
124 |
|
} |
|
125 |
|
} |
|
126 |
|
} |
|
|
117 |
|
if(str && strlen(str)>0) { |
|
118 |
|
int i; |
|
119 |
|
for(i = 0; str[i]; i++){ |
|
120 |
|
if(lowercase) { |
|
121 |
|
str[i] = tolower(str[i]); |
|
122 |
|
} else { |
|
123 |
|
str[i] = toupper(str[i]); |
|
124 |
|
} |
|
125 |
|
} |
|
126 |
|
} |
127 |
127 |
} |
} |
File src/radixsort.c changed (mode: 100644) (index 6c4cbc5..6ab0d4e) |
14 |
14 |
|
|
15 |
15 |
void radixsort_init(RadixSorter *rs, unsigned keyLimit) |
void radixsort_init(RadixSorter *rs, unsigned keyLimit) |
16 |
16 |
{ |
{ |
17 |
|
rs->optFloorAndInsertBigKeys=false; |
|
18 |
|
rs->optIgnoreBigKeys=false; |
|
19 |
|
|
|
20 |
|
rs->_topIndexLimit=GET_TOP_INDEX(keyLimit); |
|
21 |
|
rs->size=0; |
|
22 |
|
rs->topDigits=malloc(rs->_topIndexLimit * sizeof(RadixItem ***)); |
|
23 |
|
memset(rs->topDigits, 0, rs->_topIndexLimit * sizeof(RadixItem ***)); |
|
24 |
|
rs->maxKey=0; |
|
25 |
|
rs->keyLimit=keyLimit; |
|
26 |
|
|
|
27 |
|
rs->_slotDescriptors=malloc(rs->_topIndexLimit * sizeof(RadixSlot **)); |
|
28 |
|
rs->_slotsCount=0; |
|
|
17 |
|
rs->optFloorAndInsertBigKeys=false; |
|
18 |
|
rs->optIgnoreBigKeys=false; |
|
19 |
|
|
|
20 |
|
rs->_topIndexLimit=GET_TOP_INDEX(keyLimit); |
|
21 |
|
rs->size=0; |
|
22 |
|
rs->topDigits=malloc(rs->_topIndexLimit * sizeof(RadixItem ***)); |
|
23 |
|
memset(rs->topDigits, 0, rs->_topIndexLimit * sizeof(RadixItem ***)); |
|
24 |
|
rs->maxKey=0; |
|
25 |
|
rs->keyLimit=keyLimit; |
|
26 |
|
|
|
27 |
|
rs->_slotDescriptors=malloc(rs->_topIndexLimit * sizeof(RadixSlot **)); |
|
28 |
|
rs->_slotsCount=0; |
29 |
29 |
} |
} |
30 |
30 |
|
|
31 |
31 |
void radixsort_set_debug_level(RadixSorter *rs, unsigned debugLevel) |
void radixsort_set_debug_level(RadixSorter *rs, unsigned debugLevel) |
32 |
32 |
{ |
{ |
33 |
|
rs->_debug=debugLevel; |
|
|
33 |
|
rs->_debug=debugLevel; |
34 |
34 |
} |
} |
35 |
35 |
|
|
36 |
36 |
RadixItem **radixsort_get_slot(RadixSorter *rs, unsigned topIndex) |
RadixItem **radixsort_get_slot(RadixSorter *rs, unsigned topIndex) |
37 |
37 |
{ |
{ |
38 |
|
RadixItem **slot=malloc(RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
|
39 |
|
memset(slot, 0, RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
|
|
38 |
|
RadixItem **slot=malloc(RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
|
39 |
|
memset(slot, 0, RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
40 |
40 |
|
|
41 |
|
RadixSlot *descriptor=malloc(sizeof(RadixSlot)); |
|
42 |
|
descriptor->min=rs->keyLimit; |
|
43 |
|
descriptor->max=0; |
|
44 |
|
descriptor->size=0; |
|
|
41 |
|
RadixSlot *descriptor=malloc(sizeof(RadixSlot)); |
|
42 |
|
descriptor->min=rs->keyLimit; |
|
43 |
|
descriptor->max=0; |
|
44 |
|
descriptor->size=0; |
45 |
45 |
|
|
46 |
|
rs->_slotDescriptors[topIndex]=descriptor; |
|
47 |
|
rs->_slotsCount++; |
|
48 |
|
return slot; |
|
|
46 |
|
rs->_slotDescriptors[topIndex]=descriptor; |
|
47 |
|
rs->_slotsCount++; |
|
48 |
|
return slot; |
49 |
49 |
} |
} |
50 |
50 |
|
|
51 |
51 |
void radixsort_add(RadixSorter *rs, RadixItem *item) |
void radixsort_add(RadixSorter *rs, RadixItem *item) |
52 |
52 |
{ |
{ |
53 |
|
if(item->key > rs->keyLimit) { |
|
54 |
|
if(rs->_debug > RADIX_DEBUG_LEVEL_NONE) { |
|
55 |
|
fprintf(stderr, "WARNING: Radix sort overflow - inserted key is bigger than limit (%u): %u\n", rs->keyLimit, item->key); |
|
56 |
|
} |
|
57 |
|
if(rs->optFloorAndInsertBigKeys) { |
|
58 |
|
item->key = rs->keyLimit-1; |
|
59 |
|
} else { |
|
60 |
|
if(rs->optIgnoreBigKeys) { |
|
61 |
|
return; |
|
62 |
|
} else { |
|
63 |
|
exit(0); |
|
64 |
|
} |
|
65 |
|
} |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
unsigned topIndex = GET_TOP_INDEX(item->key); |
|
69 |
|
unsigned lowIndex = GET_LOW_INDEX(item->key); |
|
70 |
|
|
|
71 |
|
if(!rs->topDigits[topIndex]) { |
|
72 |
|
rs->topDigits[topIndex]=radixsort_get_slot(rs, topIndex); |
|
73 |
|
} |
|
74 |
|
|
|
75 |
|
RadixItem *chain=rs->topDigits[topIndex][lowIndex]; |
|
76 |
|
rs->topDigits[topIndex][lowIndex]=item; |
|
77 |
|
if(chain==NULL) { |
|
78 |
|
item->next=NULL; |
|
79 |
|
} else { |
|
80 |
|
item->next=chain; |
|
81 |
|
} |
|
82 |
|
|
|
83 |
|
rs->size++; |
|
84 |
|
rs->maxKey=MAX(rs->maxKey,item->key); |
|
85 |
|
rs->_slotDescriptors[topIndex]->min=MIN(rs->_slotDescriptors[topIndex]->min,item->key); |
|
86 |
|
rs->_slotDescriptors[topIndex]->max=MAX(rs->_slotDescriptors[topIndex]->max,item->key); |
|
87 |
|
rs->_slotDescriptors[topIndex]->size++; |
|
|
53 |
|
if(item->key > rs->keyLimit) { |
|
54 |
|
if(rs->_debug > RADIX_DEBUG_LEVEL_NONE) { |
|
55 |
|
fprintf(stderr, "WARNING: Radix sort overflow - inserted key is bigger than limit (%u): %u\n", rs->keyLimit, item->key); |
|
56 |
|
} |
|
57 |
|
if(rs->optFloorAndInsertBigKeys) { |
|
58 |
|
item->key = rs->keyLimit-1; |
|
59 |
|
} else { |
|
60 |
|
if(rs->optIgnoreBigKeys) { |
|
61 |
|
return; |
|
62 |
|
} else { |
|
63 |
|
exit(0); |
|
64 |
|
} |
|
65 |
|
} |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
unsigned topIndex = GET_TOP_INDEX(item->key); |
|
69 |
|
unsigned lowIndex = GET_LOW_INDEX(item->key); |
|
70 |
|
|
|
71 |
|
if(!rs->topDigits[topIndex]) { |
|
72 |
|
rs->topDigits[topIndex]=radixsort_get_slot(rs, topIndex); |
|
73 |
|
} |
|
74 |
|
|
|
75 |
|
RadixItem *chain=rs->topDigits[topIndex][lowIndex]; |
|
76 |
|
rs->topDigits[topIndex][lowIndex]=item; |
|
77 |
|
if(chain==NULL) { |
|
78 |
|
item->next=NULL; |
|
79 |
|
} else { |
|
80 |
|
item->next=chain; |
|
81 |
|
} |
|
82 |
|
|
|
83 |
|
rs->size++; |
|
84 |
|
rs->maxKey=MAX(rs->maxKey,item->key); |
|
85 |
|
rs->_slotDescriptors[topIndex]->min=MIN(rs->_slotDescriptors[topIndex]->min,item->key); |
|
86 |
|
rs->_slotDescriptors[topIndex]->max=MAX(rs->_slotDescriptors[topIndex]->max,item->key); |
|
87 |
|
rs->_slotDescriptors[topIndex]->size++; |
88 |
88 |
} |
} |
89 |
89 |
|
|
90 |
90 |
void radix_dec_slot_descriptor_size(RadixSorter *rs, RadixSlot *descriptor, unsigned key, unsigned topIndex) |
void radix_dec_slot_descriptor_size(RadixSorter *rs, RadixSlot *descriptor, unsigned key, unsigned topIndex) |
91 |
91 |
{ |
{ |
92 |
|
descriptor->size--; |
|
93 |
|
if(!descriptor->size) { |
|
94 |
|
descriptor->min=rs->keyLimit; |
|
95 |
|
descriptor->max=0; |
|
96 |
|
} else { |
|
97 |
|
if(descriptor->size==1) { |
|
98 |
|
if(rs->topDigits[topIndex][GET_LOW_INDEX(descriptor->max)]) { |
|
99 |
|
descriptor->min=descriptor->max; |
|
100 |
|
} else { |
|
101 |
|
if(rs->topDigits[topIndex][GET_LOW_INDEX(descriptor->min)]) { |
|
102 |
|
descriptor->max=descriptor->min; |
|
103 |
|
} |
|
104 |
|
} |
|
105 |
|
} |
|
106 |
|
} |
|
|
92 |
|
descriptor->size--; |
|
93 |
|
if(!descriptor->size) { |
|
94 |
|
descriptor->min=rs->keyLimit; |
|
95 |
|
descriptor->max=0; |
|
96 |
|
} else { |
|
97 |
|
if(descriptor->size==1) { |
|
98 |
|
if(rs->topDigits[topIndex][GET_LOW_INDEX(descriptor->max)]) { |
|
99 |
|
descriptor->min=descriptor->max; |
|
100 |
|
} else { |
|
101 |
|
if(rs->topDigits[topIndex][GET_LOW_INDEX(descriptor->min)]) { |
|
102 |
|
descriptor->max=descriptor->min; |
|
103 |
|
} |
|
104 |
|
} |
|
105 |
|
} |
|
106 |
|
} |
107 |
107 |
} |
} |
108 |
108 |
|
|
109 |
109 |
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data) |
RadixItem *radix_cut(RadixSorter *rs, unsigned key, void *data) |
110 |
110 |
{ |
{ |
111 |
|
// TODO optimization: fix min/max on cut of a value |
|
112 |
|
if(key <= rs->maxKey) { |
|
113 |
|
unsigned topIndex = GET_TOP_INDEX(key); |
|
114 |
|
unsigned lowIndex = GET_LOW_INDEX(key); |
|
115 |
|
|
|
116 |
|
if(rs->topDigits[topIndex]) { |
|
117 |
|
RadixItem *ri=rs->topDigits[topIndex][lowIndex]; |
|
118 |
|
RadixItem *lastRi=NULL; |
|
119 |
|
while(ri->data!=data) { |
|
120 |
|
if(ri->next) { |
|
121 |
|
lastRi=ri; |
|
122 |
|
ri=ri->next; |
|
123 |
|
} else { |
|
124 |
|
break; |
|
125 |
|
} |
|
126 |
|
} |
|
127 |
|
if(ri->data==data) { |
|
128 |
|
if(lastRi) { |
|
129 |
|
lastRi->next=ri->next; |
|
130 |
|
} else { |
|
131 |
|
rs->topDigits[topIndex][lowIndex]=ri->next; |
|
132 |
|
} |
|
133 |
|
ri->next=NULL; |
|
134 |
|
rs->size--; |
|
135 |
|
radix_dec_slot_descriptor_size(rs, rs->_slotDescriptors[topIndex], key, topIndex); |
|
136 |
|
return ri; |
|
137 |
|
} |
|
138 |
|
} |
|
139 |
|
} |
|
140 |
|
return NULL; |
|
|
111 |
|
// TODO optimization: fix min/max on cut of a value |
|
112 |
|
if(key <= rs->maxKey) { |
|
113 |
|
unsigned topIndex = GET_TOP_INDEX(key); |
|
114 |
|
unsigned lowIndex = GET_LOW_INDEX(key); |
|
115 |
|
|
|
116 |
|
if(rs->topDigits[topIndex]) { |
|
117 |
|
RadixItem *ri=rs->topDigits[topIndex][lowIndex]; |
|
118 |
|
RadixItem *lastRi=NULL; |
|
119 |
|
while(ri->data!=data) { |
|
120 |
|
if(ri->next) { |
|
121 |
|
lastRi=ri; |
|
122 |
|
ri=ri->next; |
|
123 |
|
} else { |
|
124 |
|
break; |
|
125 |
|
} |
|
126 |
|
} |
|
127 |
|
if(ri->data==data) { |
|
128 |
|
if(lastRi) { |
|
129 |
|
lastRi->next=ri->next; |
|
130 |
|
} else { |
|
131 |
|
rs->topDigits[topIndex][lowIndex]=ri->next; |
|
132 |
|
} |
|
133 |
|
ri->next=NULL; |
|
134 |
|
rs->size--; |
|
135 |
|
radix_dec_slot_descriptor_size(rs, rs->_slotDescriptors[topIndex], key, topIndex); |
|
136 |
|
return ri; |
|
137 |
|
} |
|
138 |
|
} |
|
139 |
|
} |
|
140 |
|
return NULL; |
141 |
141 |
} |
} |
142 |
142 |
|
|
143 |
143 |
RadixItem **radixsort_dump(RadixSorter *rs) |
RadixItem **radixsort_dump(RadixSorter *rs) |
144 |
144 |
{ |
{ |
145 |
|
if(rs->size>0) { |
|
146 |
|
RadixItem **result=malloc(rs->size * sizeof(RadixItem *)); |
|
147 |
|
int t = GET_TOP_INDEX(rs->maxKey); |
|
148 |
|
int slotMin, slotSize, slotCount, l; |
|
149 |
|
unsigned items=0; |
|
150 |
|
do { |
|
151 |
|
if(rs->topDigits[t]) { |
|
152 |
|
if(rs->_slotDescriptors[t]->size>0) { |
|
153 |
|
l=GET_LOW_INDEX(rs->_slotDescriptors[t]->max); |
|
154 |
|
slotMin=GET_LOW_INDEX(rs->_slotDescriptors[t]->min); |
|
155 |
|
slotSize=rs->_slotDescriptors[t]->size; |
|
156 |
|
slotCount=0; |
|
157 |
|
do { |
|
158 |
|
if(rs->topDigits[t][l]) { |
|
159 |
|
result[items++]=rs->topDigits[t][l]; |
|
160 |
|
slotCount++; |
|
161 |
|
RadixItem *ri=rs->topDigits[t][l]->next; |
|
162 |
|
while(ri) { |
|
163 |
|
result[items++]=ri; |
|
164 |
|
slotCount++; |
|
165 |
|
ri=ri->next; |
|
166 |
|
} |
|
167 |
|
} |
|
168 |
|
} while(--l>=slotMin && slotCount<slotSize); |
|
169 |
|
} |
|
170 |
|
} |
|
171 |
|
} while(--t>=0); |
|
172 |
|
return result; |
|
173 |
|
} |
|
174 |
|
return NULL; |
|
|
145 |
|
if(rs->size>0) { |
|
146 |
|
RadixItem **result=malloc(rs->size * sizeof(RadixItem *)); |
|
147 |
|
int t = GET_TOP_INDEX(rs->maxKey); |
|
148 |
|
int slotMin, slotSize, slotCount, l; |
|
149 |
|
unsigned items=0; |
|
150 |
|
do { |
|
151 |
|
if(rs->topDigits[t]) { |
|
152 |
|
if(rs->_slotDescriptors[t]->size>0) { |
|
153 |
|
l=GET_LOW_INDEX(rs->_slotDescriptors[t]->max); |
|
154 |
|
slotMin=GET_LOW_INDEX(rs->_slotDescriptors[t]->min); |
|
155 |
|
slotSize=rs->_slotDescriptors[t]->size; |
|
156 |
|
slotCount=0; |
|
157 |
|
do { |
|
158 |
|
if(rs->topDigits[t][l]) { |
|
159 |
|
result[items++]=rs->topDigits[t][l]; |
|
160 |
|
slotCount++; |
|
161 |
|
RadixItem *ri=rs->topDigits[t][l]->next; |
|
162 |
|
while(ri) { |
|
163 |
|
result[items++]=ri; |
|
164 |
|
slotCount++; |
|
165 |
|
ri=ri->next; |
|
166 |
|
} |
|
167 |
|
} |
|
168 |
|
} while(--l>=slotMin && slotCount<slotSize); |
|
169 |
|
} |
|
170 |
|
} |
|
171 |
|
} while(--t>=0); |
|
172 |
|
return result; |
|
173 |
|
} |
|
174 |
|
return NULL; |
175 |
175 |
} |
} |
176 |
176 |
|
|
177 |
177 |
void radixsort_stat(RadixSorter *rs, bool listing) |
void radixsort_stat(RadixSorter *rs, bool listing) |
178 |
178 |
{ |
{ |
179 |
|
printf("\n Radixsort (size/max/limit/slot count): %u %u %u %u", rs->size, rs->maxKey, rs->keyLimit, rs->_slotsCount); |
|
180 |
|
unsigned memory=rs->_topIndexLimit * sizeof(RadixItem ***); |
|
181 |
|
memory+=memory; |
|
182 |
|
memory+=rs->_slotsCount*(RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
|
183 |
|
printf("\n Memory: %u\n", memory); |
|
184 |
|
if(listing && rs->size>0) { |
|
185 |
|
int t = GET_TOP_INDEX(rs->maxKey); |
|
186 |
|
int slotMin, slotSize, slotCount, l; |
|
187 |
|
unsigned items=0; |
|
188 |
|
do { |
|
189 |
|
if(rs->topDigits[t]) { |
|
190 |
|
printf("\n Slot %u (size/min/max): %u %u %u",t, rs->_slotDescriptors[t]->size, rs->_slotDescriptors[t]->min, rs->_slotDescriptors[t]->max); |
|
191 |
|
if(rs->_slotDescriptors[t]->size>0) { |
|
192 |
|
l=GET_LOW_INDEX(rs->_slotDescriptors[t]->max); |
|
193 |
|
slotMin=GET_LOW_INDEX(rs->_slotDescriptors[t]->min); |
|
194 |
|
slotSize=rs->_slotDescriptors[t]->size; |
|
195 |
|
slotCount=0; |
|
196 |
|
do { |
|
197 |
|
if(rs->topDigits[t][l]) { |
|
198 |
|
printf("\n > %d #%u",l, ++items); |
|
199 |
|
++slotCount; |
|
200 |
|
RadixItem *ri=rs->topDigits[t][l]->next; |
|
201 |
|
while(ri) { |
|
202 |
|
printf(" #%u",++items); |
|
203 |
|
++slotCount; |
|
204 |
|
ri=ri->next; |
|
205 |
|
} |
|
206 |
|
} |
|
207 |
|
} while(--l>=slotMin && slotCount<slotSize); |
|
208 |
|
printf("\n STOP @ %d",l); |
|
209 |
|
} else { |
|
210 |
|
printf(" > SKIPPED"); |
|
211 |
|
} |
|
212 |
|
} |
|
213 |
|
} while(--t>=0); |
|
214 |
|
} |
|
215 |
|
fflush(stdout); |
|
|
179 |
|
printf("\n Radixsort (size/max/limit/slot count): %u %u %u %u", rs->size, rs->maxKey, rs->keyLimit, rs->_slotsCount); |
|
180 |
|
unsigned memory=rs->_topIndexLimit * sizeof(RadixItem ***); |
|
181 |
|
memory+=memory; |
|
182 |
|
memory+=rs->_slotsCount*(RADIX_SLOT_SIZE * sizeof(RadixItem *)); |
|
183 |
|
printf("\n Memory: %u\n", memory); |
|
184 |
|
if(listing && rs->size>0) { |
|
185 |
|
int t = GET_TOP_INDEX(rs->maxKey); |
|
186 |
|
int slotMin, slotSize, slotCount, l; |
|
187 |
|
unsigned items=0; |
|
188 |
|
do { |
|
189 |
|
if(rs->topDigits[t]) { |
|
190 |
|
printf("\n Slot %u (size/min/max): %u %u %u",t, rs->_slotDescriptors[t]->size, rs->_slotDescriptors[t]->min, rs->_slotDescriptors[t]->max); |
|
191 |
|
if(rs->_slotDescriptors[t]->size>0) { |
|
192 |
|
l=GET_LOW_INDEX(rs->_slotDescriptors[t]->max); |
|
193 |
|
slotMin=GET_LOW_INDEX(rs->_slotDescriptors[t]->min); |
|
194 |
|
slotSize=rs->_slotDescriptors[t]->size; |
|
195 |
|
slotCount=0; |
|
196 |
|
do { |
|
197 |
|
if(rs->topDigits[t][l]) { |
|
198 |
|
printf("\n > %d #%u",l, ++items); |
|
199 |
|
++slotCount; |
|
200 |
|
RadixItem *ri=rs->topDigits[t][l]->next; |
|
201 |
|
while(ri) { |
|
202 |
|
printf(" #%u",++items); |
|
203 |
|
++slotCount; |
|
204 |
|
ri=ri->next; |
|
205 |
|
} |
|
206 |
|
} |
|
207 |
|
} while(--l>=slotMin && slotCount<slotSize); |
|
208 |
|
printf("\n STOP @ %d",l); |
|
209 |
|
} else { |
|
210 |
|
printf(" > SKIPPED"); |
|
211 |
|
} |
|
212 |
|
} |
|
213 |
|
} while(--t>=0); |
|
214 |
|
} |
|
215 |
|
fflush(stdout); |
216 |
216 |
} |
} |
217 |
217 |
|
|
218 |
218 |
void radixsort_destroy(RadixSorter *rs) |
void radixsort_destroy(RadixSorter *rs) |
219 |
219 |
{ |
{ |
220 |
|
// radix items: DONE (passed on dump() by reference) |
|
221 |
|
// rs: DONE (created and destroyed by caller) |
|
222 |
|
// slots: |
|
223 |
|
int topIndex = GET_TOP_INDEX(rs->maxKey); |
|
224 |
|
do { |
|
225 |
|
if(rs->topDigits[topIndex]) { |
|
226 |
|
free(rs->topDigits[topIndex]); |
|
227 |
|
free(rs->_slotDescriptors[topIndex]); |
|
228 |
|
} |
|
229 |
|
} while(--topIndex>=0); |
|
|
220 |
|
// radix items: DONE (passed on dump() by reference) |
|
221 |
|
// rs: DONE (created and destroyed by caller) |
|
222 |
|
// slots: |
|
223 |
|
int topIndex = GET_TOP_INDEX(rs->maxKey); |
|
224 |
|
do { |
|
225 |
|
if(rs->topDigits[topIndex]) { |
|
226 |
|
free(rs->topDigits[topIndex]); |
|
227 |
|
free(rs->_slotDescriptors[topIndex]); |
|
228 |
|
} |
|
229 |
|
} while(--topIndex>=0); |
230 |
230 |
} |
} |
File tests/src/test_getopt.c changed (mode: 100644) (index 4b4a32e..c421017) |
13 |
13 |
|
|
14 |
14 |
int main(int argc, char **argv) |
int main(int argc, char **argv) |
15 |
15 |
{ |
{ |
16 |
|
int c; |
|
17 |
|
int digit_optind = 0; |
|
18 |
|
|
|
19 |
|
while (1) { |
|
20 |
|
int this_option_optind = optind ? optind : 1; |
|
21 |
|
int option_index = 0; |
|
22 |
|
static struct option long_options[] = { |
|
23 |
|
{"add", required_argument, 0, 0 }, |
|
24 |
|
{"append", no_argument, 0, 0 }, |
|
25 |
|
{"delete", required_argument, 0, 0 }, |
|
26 |
|
{"verbose", no_argument, 0, 0 }, |
|
27 |
|
{"create", required_argument, 0, 'c'}, |
|
28 |
|
{"file", required_argument, 0, 0 }, |
|
29 |
|
{0, 0, 0, 0 } |
|
30 |
|
}; |
|
31 |
|
|
|
32 |
|
c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index); |
|
33 |
|
if (c == -1) |
|
34 |
|
break; |
|
35 |
|
|
|
36 |
|
|
|
37 |
|
switch (c) { |
|
38 |
|
case 0: |
|
39 |
|
printf("option %s", long_options[option_index].name); |
|
40 |
|
if (optarg) |
|
41 |
|
printf(" with arg %s", optarg); |
|
42 |
|
printf("\n"); |
|
43 |
|
break; |
|
44 |
|
|
|
45 |
|
case '0': |
|
46 |
|
case '1': |
|
47 |
|
case '2': |
|
48 |
|
if (digit_optind != 0 && digit_optind != this_option_optind) |
|
49 |
|
printf("digits occur in two different argv-elements.\n"); |
|
50 |
|
digit_optind = this_option_optind; |
|
51 |
|
printf("option %c\n", c); |
|
52 |
|
break; |
|
53 |
|
|
|
54 |
|
case 'a': |
|
55 |
|
printf("option a\n"); |
|
56 |
|
break; |
|
57 |
|
|
|
58 |
|
case 'b': |
|
59 |
|
printf("option b\n"); |
|
60 |
|
break; |
|
61 |
|
|
|
62 |
|
case 'c': |
|
63 |
|
printf("option c with value '%s'\n", optarg); |
|
64 |
|
break; |
|
65 |
|
|
|
66 |
|
case 'd': |
|
67 |
|
printf("option d with value '%s'\n", optarg); |
|
68 |
|
break; |
|
69 |
|
|
|
70 |
|
case '?': |
|
71 |
|
|
|
72 |
|
break; |
|
73 |
|
|
|
74 |
|
default: |
|
75 |
|
printf("?? getopt returned character code 0%o ??\n", c); |
|
76 |
|
} |
|
77 |
|
} |
|
78 |
|
|
|
79 |
|
if (optind < argc) { |
|
80 |
|
printf("non-option ARGV-elements: "); |
|
81 |
|
while (optind < argc) |
|
82 |
|
printf("%s ", argv[optind++]); |
|
83 |
|
printf("\n"); |
|
84 |
|
} |
|
85 |
|
|
|
86 |
|
exit(EXIT_SUCCESS); |
|
|
16 |
|
int c; |
|
17 |
|
int digit_optind = 0; |
|
18 |
|
|
|
19 |
|
while (1) { |
|
20 |
|
int this_option_optind = optind ? optind : 1; |
|
21 |
|
int option_index = 0; |
|
22 |
|
static struct option long_options[] = { |
|
23 |
|
{"add", required_argument, 0, 0 }, |
|
24 |
|
{"append", no_argument, 0, 0 }, |
|
25 |
|
{"delete", required_argument, 0, 0 }, |
|
26 |
|
{"verbose", no_argument, 0, 0 }, |
|
27 |
|
{"create", required_argument, 0, 'c'}, |
|
28 |
|
{"file", required_argument, 0, 0 }, |
|
29 |
|
{0, 0, 0, 0 } |
|
30 |
|
}; |
|
31 |
|
|
|
32 |
|
c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index); |
|
33 |
|
if (c == -1) |
|
34 |
|
break; |
|
35 |
|
|
|
36 |
|
|
|
37 |
|
switch (c) { |
|
38 |
|
case 0: |
|
39 |
|
printf("option %s", long_options[option_index].name); |
|
40 |
|
if (optarg) |
|
41 |
|
printf(" with arg %s", optarg); |
|
42 |
|
printf("\n"); |
|
43 |
|
break; |
|
44 |
|
|
|
45 |
|
case '0': |
|
46 |
|
case '1': |
|
47 |
|
case '2': |
|
48 |
|
if (digit_optind != 0 && digit_optind != this_option_optind) |
|
49 |
|
printf("digits occur in two different argv-elements.\n"); |
|
50 |
|
digit_optind = this_option_optind; |
|
51 |
|
printf("option %c\n", c); |
|
52 |
|
break; |
|
53 |
|
|
|
54 |
|
case 'a': |
|
55 |
|
printf("option a\n"); |
|
56 |
|
break; |
|
57 |
|
|
|
58 |
|
case 'b': |
|
59 |
|
printf("option b\n"); |
|
60 |
|
break; |
|
61 |
|
|
|
62 |
|
case 'c': |
|
63 |
|
printf("option c with value '%s'\n", optarg); |
|
64 |
|
break; |
|
65 |
|
|
|
66 |
|
case 'd': |
|
67 |
|
printf("option d with value '%s'\n", optarg); |
|
68 |
|
break; |
|
69 |
|
|
|
70 |
|
case '?': |
|
71 |
|
|
|
72 |
|
break; |
|
73 |
|
|
|
74 |
|
default: |
|
75 |
|
printf("?? getopt returned character code 0%o ??\n", c); |
|
76 |
|
} |
|
77 |
|
} |
|
78 |
|
|
|
79 |
|
if (optind < argc) { |
|
80 |
|
printf("non-option ARGV-elements: "); |
|
81 |
|
while (optind < argc) |
|
82 |
|
printf("%s ", argv[optind++]); |
|
83 |
|
printf("\n"); |
|
84 |
|
} |
|
85 |
|
|
|
86 |
|
exit(EXIT_SUCCESS); |
87 |
87 |
} |
} |
File tests/src/test_hashset.c changed (mode: 100644) (index ec42edd..7291acc) |
11 |
11 |
#include "../../src/include/hstr_utils.h" |
#include "../../src/include/hstr_utils.h" |
12 |
12 |
|
|
13 |
13 |
void testBlacklist() { |
void testBlacklist() { |
14 |
|
const char* commandBlacklist[] = { "a","b","c","d","e" }; |
|
15 |
|
HashSet blacklist; |
|
16 |
|
int i; |
|
17 |
|
hashset_init(&blacklist); |
|
18 |
|
for (i = 0; i < 5; i++) { |
|
19 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
20 |
|
} |
|
21 |
|
for (i = 0; i < 5; i++) { |
|
22 |
|
printf("match %d\n", hashset_contains(&blacklist, hstr_strdup(commandBlacklist[i]))); |
|
23 |
|
} |
|
|
14 |
|
const char* commandBlacklist[] = { "a","b","c","d","e" }; |
|
15 |
|
HashSet blacklist; |
|
16 |
|
int i; |
|
17 |
|
hashset_init(&blacklist); |
|
18 |
|
for (i = 0; i < 5; i++) { |
|
19 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
20 |
|
} |
|
21 |
|
for (i = 0; i < 5; i++) { |
|
22 |
|
printf("match %d\n", hashset_contains(&blacklist, hstr_strdup(commandBlacklist[i]))); |
|
23 |
|
} |
24 |
24 |
} |
} |
25 |
25 |
|
|
26 |
26 |
void testGetKeys() { |
void testGetKeys() { |
27 |
|
const char* commandBlacklist[] = { "a","b","c","d","e" }; |
|
28 |
|
HashSet blacklist; |
|
29 |
|
int i; |
|
30 |
|
hashset_init(&blacklist); |
|
31 |
|
for (i = 0; i < 5; i++) { |
|
32 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
33 |
|
} |
|
|
27 |
|
const char* commandBlacklist[] = { "a","b","c","d","e" }; |
|
28 |
|
HashSet blacklist; |
|
29 |
|
int i; |
|
30 |
|
hashset_init(&blacklist); |
|
31 |
|
for (i = 0; i < 5; i++) { |
|
32 |
|
hashset_add(&blacklist, commandBlacklist[i]); |
|
33 |
|
} |
34 |
34 |
|
|
35 |
|
char **keys=hashset_keys(&blacklist); |
|
36 |
|
if(keys) { |
|
37 |
|
for(i=0; i<hashset_size(&blacklist); i++) { |
|
38 |
|
printf("\nKey: %s", keys[i]); |
|
39 |
|
} |
|
40 |
|
} |
|
|
35 |
|
char **keys=hashset_keys(&blacklist); |
|
36 |
|
if(keys) { |
|
37 |
|
for(i=0; i<hashset_size(&blacklist); i++) { |
|
38 |
|
printf("\nKey: %s", keys[i]); |
|
39 |
|
} |
|
40 |
|
} |
41 |
41 |
} |
} |
42 |
42 |
|
|
43 |
43 |
int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
44 |
44 |
{ |
{ |
45 |
|
testGetKeys(); |
|
|
45 |
|
testGetKeys(); |
46 |
46 |
} |
} |
File tests/src/test_ranking.c changed (mode: 100644) (index 7c5090d..ab1bca7) |
11 |
11 |
#include <math.h> |
#include <math.h> |
12 |
12 |
|
|
13 |
13 |
void testLog() { |
void testLog() { |
14 |
|
const int HISTORY_SIZE=2000; |
|
15 |
|
int i; |
|
16 |
|
for(i=0; i<HISTORY_SIZE; i++) { |
|
17 |
|
printf("\n%d # l: %f # l10: %f # l2: %f", i, log(i), log10(i), log2(i)); |
|
18 |
|
} |
|
|
14 |
|
const int HISTORY_SIZE=2000; |
|
15 |
|
int i; |
|
16 |
|
for(i=0; i<HISTORY_SIZE; i++) { |
|
17 |
|
printf("\n%d # l: %f # l10: %f # l2: %f", i, log(i), log10(i), log2(i)); |
|
18 |
|
} |
19 |
19 |
} |
} |
20 |
20 |
|
|
21 |
21 |
#define MAX_CHARACTER_CODE 10000 |
#define MAX_CHARACTER_CODE 10000 |
|
... |
... |
static char line[MAX_CHARACTER_CODE]; |
23 |
23 |
|
|
24 |
24 |
void testGenerateHugeHistoryFileWithDifferentLines() |
void testGenerateHugeHistoryFileWithDifferentLines() |
25 |
25 |
{ |
{ |
26 |
|
FILE *file = fopen(".bash_history_huge","a"); |
|
27 |
|
fseek(file,0, SEEK_END); |
|
|
26 |
|
FILE *file = fopen(".bash_history_huge","a"); |
|
27 |
|
fseek(file,0, SEEK_END); |
28 |
28 |
|
|
29 |
|
line[0]=0; |
|
30 |
|
int i; |
|
31 |
|
for(i=0; i<MAX_CHARACTER_CODE; i++) { |
|
32 |
|
sprintf(line,"%s%c",line,i); |
|
33 |
|
fprintf(file,"%s\n",line); |
|
34 |
|
} |
|
35 |
|
fclose(file); |
|
|
29 |
|
line[0]=0; |
|
30 |
|
int i; |
|
31 |
|
for(i=0; i<MAX_CHARACTER_CODE; i++) { |
|
32 |
|
sprintf(line,"%s%c",line,i); |
|
33 |
|
fprintf(file,"%s\n",line); |
|
34 |
|
} |
|
35 |
|
fclose(file); |
36 |
36 |
} |
} |
37 |
37 |
|
|
38 |
38 |
|
|
39 |
39 |
void testGenerateHugeHistoryFileWithSameLines() |
void testGenerateHugeHistoryFileWithSameLines() |
40 |
40 |
{ |
{ |
41 |
|
FILE *file = fopen(".bash_history_same","a"); |
|
42 |
|
fseek(file,0, SEEK_END); |
|
|
41 |
|
FILE *file = fopen(".bash_history_same","a"); |
|
42 |
|
fseek(file,0, SEEK_END); |
43 |
43 |
|
|
44 |
|
int i; |
|
45 |
|
for(i=0; i<100000; i++) { |
|
46 |
|
fprintf(file,"find . | while read X; do echo $X; cat $X | grep -i ctrl; done | less\n",line); |
|
47 |
|
fprintf(file, |
|
48 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
49 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
50 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
51 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
52 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
53 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
54 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master\n", |
|
55 |
|
line); |
|
56 |
|
} |
|
57 |
|
fclose(file); |
|
|
44 |
|
int i; |
|
45 |
|
for(i=0; i<100000; i++) { |
|
46 |
|
fprintf(file,"find . | while read X; do echo $X; cat $X | grep -i ctrl; done | less\n",line); |
|
47 |
|
fprintf(file, |
|
48 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
49 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
50 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
51 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
52 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
53 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master#" |
|
54 |
|
"git commit -a -m \"Code review and stabilization.\" && git push origin master\n", |
|
55 |
|
line); |
|
56 |
|
} |
|
57 |
|
fclose(file); |
58 |
58 |
} |
} |
59 |
59 |
|
|
60 |
60 |
|
|
61 |
61 |
int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
62 |
62 |
{ |
{ |
63 |
|
testGenerateHugeHistoryFileWithSameLines(); |
|
|
63 |
|
testGenerateHugeHistoryFileWithSameLines(); |
64 |
64 |
} |
} |
65 |
65 |
|
|
File tests/src/test_regexp.c changed (mode: 100644) (index 06982df..85d4300) |
14 |
14 |
#define REGEXP_MATCH_BUFFER_SIZE 10 |
#define REGEXP_MATCH_BUFFER_SIZE 10 |
15 |
15 |
|
|
16 |
16 |
void main() { |
void main() { |
17 |
|
bool caseSensitive=false; |
|
18 |
|
|
|
19 |
|
char *regexp="^b"; |
|
20 |
|
char *text="This is a command that I want to match: go.sh there"; |
|
21 |
|
|
|
22 |
|
regex_t compiled; |
|
23 |
|
int compilationFlags=(caseSensitive?0:REG_ICASE); |
|
24 |
|
printf("Regular expressions matching:\n '%s'\n '%s'",text,regexp); |
|
25 |
|
int compilationStatus=regcomp(&compiled, regexp, compilationFlags); |
|
26 |
|
printf("\nCompilation: %d",compilationStatus); |
|
27 |
|
|
|
28 |
|
int matches=REGEXP_MATCH_BUFFER_SIZE; |
|
29 |
|
regmatch_t matchPtr[REGEXP_MATCH_BUFFER_SIZE]; |
|
30 |
|
int matchingFlags=0; |
|
31 |
|
int matchingStatus=regexec(&compiled, text, matches, matchPtr, matchingFlags); |
|
32 |
|
printf("\nMatching (status/matches): %s %d",(!matchingStatus?"match":"no-match"),matches); |
|
33 |
|
|
|
34 |
|
if(!matchingStatus) { |
|
35 |
|
int i; |
|
36 |
|
for(i=0; i<REGEXP_MATCH_BUFFER_SIZE; i++) { |
|
37 |
|
printf("\n %d %d",matchPtr[i].rm_so, matchPtr[i].rm_eo); |
|
38 |
|
if(matchPtr[i].rm_so != -1) { |
|
39 |
|
printf("\n* %d %d",matchPtr[i].rm_so,matchPtr[i].rm_eo); |
|
40 |
|
} |
|
41 |
|
} |
|
42 |
|
} else { |
|
43 |
|
regerror(matchingStatus); |
|
44 |
|
} |
|
45 |
|
|
|
46 |
|
printf("\n"); |
|
|
17 |
|
bool caseSensitive=false; |
|
18 |
|
|
|
19 |
|
char *regexp="^b"; |
|
20 |
|
char *text="This is a command that I want to match: go.sh there"; |
|
21 |
|
|
|
22 |
|
regex_t compiled; |
|
23 |
|
int compilationFlags=(caseSensitive?0:REG_ICASE); |
|
24 |
|
printf("Regular expressions matching:\n '%s'\n '%s'",text,regexp); |
|
25 |
|
int compilationStatus=regcomp(&compiled, regexp, compilationFlags); |
|
26 |
|
printf("\nCompilation: %d",compilationStatus); |
|
27 |
|
|
|
28 |
|
int matches=REGEXP_MATCH_BUFFER_SIZE; |
|
29 |
|
regmatch_t matchPtr[REGEXP_MATCH_BUFFER_SIZE]; |
|
30 |
|
int matchingFlags=0; |
|
31 |
|
int matchingStatus=regexec(&compiled, text, matches, matchPtr, matchingFlags); |
|
32 |
|
printf("\nMatching (status/matches): %s %d",(!matchingStatus?"match":"no-match"),matches); |
|
33 |
|
|
|
34 |
|
if(!matchingStatus) { |
|
35 |
|
int i; |
|
36 |
|
for(i=0; i<REGEXP_MATCH_BUFFER_SIZE; i++) { |
|
37 |
|
printf("\n %d %d",matchPtr[i].rm_so, matchPtr[i].rm_eo); |
|
38 |
|
if(matchPtr[i].rm_so != -1) { |
|
39 |
|
printf("\n* %d %d",matchPtr[i].rm_so,matchPtr[i].rm_eo); |
|
40 |
|
} |
|
41 |
|
} |
|
42 |
|
} else { |
|
43 |
|
regerror(matchingStatus); |
|
44 |
|
} |
|
45 |
|
|
|
46 |
|
printf("\n"); |
47 |
47 |
} |
} |
File tests/src/test_utf8.c changed (mode: 100644) (index 98ba726..b619a1c) |
... |
... |
void console_echo_czech() |
45 |
45 |
} |
} |
46 |
46 |
|
|
47 |
47 |
void loop_string() { |
void loop_string() { |
48 |
|
// char *s="a"; |
|
49 |
|
char *s="Ča"; |
|
50 |
|
// char *s="Čeština"; |
|
51 |
|
int i; |
|
52 |
|
for(i=0; i<10; i++) { |
|
53 |
|
printf("\n%d",s[i]); |
|
54 |
|
show_bits(s[i]); |
|
55 |
|
if(!s[i]) break; |
|
56 |
|
} |
|
|
48 |
|
// char *s="a"; |
|
49 |
|
char *s="Ča"; |
|
50 |
|
// char *s="Čeština"; |
|
51 |
|
int i; |
|
52 |
|
for(i=0; i<10; i++) { |
|
53 |
|
printf("\n%d",s[i]); |
|
54 |
|
show_bits(s[i]); |
|
55 |
|
if(!s[i]) break; |
|
56 |
|
} |
57 |
57 |
} |
} |
58 |
58 |
|
|
59 |
59 |
void get_string_length() { |
void get_string_length() { |
60 |
|
char *s="Čeština"; |
|
61 |
|
wchar_t *w=L"Čeština"; |
|
62 |
|
|
|
63 |
|
printf("%s (7): strlen(): %zd, mbstowcs(): %zd, wcslen(): %zd", |
|
64 |
|
s, |
|
65 |
|
strlen(s), |
|
66 |
|
mbstowcs(NULL,s,0), |
|
67 |
|
wcslen(w)); // OK |
|
|
60 |
|
char *s="Čeština"; |
|
61 |
|
wchar_t *w=L"Čeština"; |
|
62 |
|
|
|
63 |
|
printf("%s (7): strlen(): %zd, mbstowcs(): %zd, wcslen(): %zd", |
|
64 |
|
s, |
|
65 |
|
strlen(s), |
|
66 |
|
mbstowcs(NULL,s,0), |
|
67 |
|
wcslen(w)); // OK |
68 |
68 |
} |
} |
69 |
69 |
|
|
70 |
70 |
void console_static_wide_czech() |
void console_static_wide_czech() |
|
... |
... |
void console_static_wide_czech() |
74 |
74 |
wchar_t *w=L"Čeština."; // wide |
wchar_t *w=L"Čeština."; // wide |
75 |
75 |
char multibyte[100]; // multi-byte |
char multibyte[100]; // multi-byte |
76 |
76 |
if(iswprint(*w)) { |
if(iswprint(*w)) { |
77 |
|
printf("\nString to be printed is UTF8 wide!"); |
|
78 |
|
int offset=wctomb(multibyte, w); |
|
79 |
|
printf("\nStatic (wide) printf: %s", multibyte); |
|
|
77 |
|
printf("\nString to be printed is UTF8 wide!"); |
|
78 |
|
int offset=wctomb(multibyte, w); |
|
79 |
|
printf("\nStatic (wide) printf: %s", multibyte); |
80 |
80 |
} else { |
} else { |
81 |
|
printf("\nString to be printed is NOT UTF8 wide!"); |
|
82 |
|
wprintf(L"\nStatic wprintf: %ls", w); |
|
|
81 |
|
printf("\nString to be printed is NOT UTF8 wide!"); |
|
82 |
|
wprintf(L"\nStatic wprintf: %ls", w); |
83 |
83 |
} |
} |
84 |
84 |
} |
} |
85 |
85 |
|
|
|
... |
... |
void curses_wide_czech() |
112 |
112 |
} |
} |
113 |
113 |
|
|
114 |
114 |
void print_char_bits(int y, int x, char c) { |
void print_char_bits(int y, int x, char c) { |
115 |
|
int i; |
|
|
115 |
|
int i; |
116 |
116 |
static int intSizeInBits = sizeof(char) * 8; |
static int intSizeInBits = sizeof(char) * 8; |
117 |
117 |
static char symbol[2] = {'0','1'}; |
static char symbol[2] = {'0','1'}; |
118 |
118 |
char * binary = (char *)malloc(intSizeInBits + 1); |
char * binary = (char *)malloc(intSizeInBits + 1); |
|
... |
... |
void print_char_bits(int y, int x, char c) { |
126 |
126 |
} |
} |
127 |
127 |
|
|
128 |
128 |
void getch_with_counter_curses() { |
void getch_with_counter_curses() { |
129 |
|
// TODO implement getch with counter; getch result analysis (trip); append analysis; ... |
|
130 |
|
|
|
131 |
|
initscr(); |
|
132 |
|
keypad(stdscr, TRUE); |
|
133 |
|
noecho(); |
|
134 |
|
start_color(); |
|
135 |
|
use_default_colors(); |
|
136 |
|
|
|
137 |
|
char pattern[512]; |
|
138 |
|
int c; |
|
139 |
|
|
|
140 |
|
pattern[0]=0; |
|
141 |
|
while (1) { |
|
142 |
|
c = wgetch(stdscr); |
|
143 |
|
strcat(pattern, (char*)(&c)); |
|
144 |
|
mvprintw(2, 0, "Pattern '%s'", pattern); |
|
145 |
|
mvprintw(3, 0, "Char '%d'", c); |
|
146 |
|
|
|
147 |
|
mvprintw(6, 0, "strlen() '%d'", strlen(pattern)); |
|
148 |
|
mvprintw(7, 0, "mbstowcs() '%d'", mbstowcs(NULL,pattern,0)); |
|
149 |
|
|
|
150 |
|
int i; |
|
151 |
|
int intSizeInBits = sizeof(int) * 8; |
|
152 |
|
char symbol[2] = {'0','1'}; |
|
153 |
|
char * binary = (char *)malloc(intSizeInBits + 1); |
|
154 |
|
memset(binary, 0, intSizeInBits + 1); |
|
155 |
|
for (i=0; i< intSizeInBits; i++) { |
|
156 |
|
binary[intSizeInBits-i-1] = symbol[(c>>i) & 0x01]; |
|
157 |
|
} |
|
158 |
|
mvprintw(10, 0, "bits: %s", binary); |
|
159 |
|
free(binary); |
|
160 |
|
|
|
161 |
|
mvprintw(11, 0, "high bit: %d %d ", 1<<7, 1<<7 & c); |
|
162 |
|
|
|
163 |
|
char cc=pattern[0]; |
|
164 |
|
i=0; |
|
165 |
|
int myStrlen=0; |
|
166 |
|
char isHighBitSet=0; |
|
167 |
|
while(cc) { |
|
168 |
|
print_char_bits(12, 9*i-8, pattern[i++]); |
|
169 |
|
cc=pattern[i]; |
|
170 |
|
|
|
171 |
|
if(1<<7 & pattern[i]) { |
|
172 |
|
if(isHighBitSet) { |
|
173 |
|
isHighBitSet=0; |
|
174 |
|
myStrlen++; |
|
175 |
|
} else { |
|
176 |
|
isHighBitSet=1; |
|
177 |
|
} |
|
178 |
|
} else { |
|
179 |
|
myStrlen++; |
|
180 |
|
} |
|
181 |
|
} |
|
182 |
|
|
|
183 |
|
mvprintw(14, 0, "mystrlen(): %d ", myStrlen); |
|
184 |
|
} |
|
|
129 |
|
// TODO implement getch with counter; getch result analysis (trip); append analysis; ... |
|
130 |
|
|
|
131 |
|
initscr(); |
|
132 |
|
keypad(stdscr, TRUE); |
|
133 |
|
noecho(); |
|
134 |
|
start_color(); |
|
135 |
|
use_default_colors(); |
|
136 |
|
|
|
137 |
|
char pattern[512]; |
|
138 |
|
int c; |
|
139 |
|
|
|
140 |
|
pattern[0]=0; |
|
141 |
|
while (1) { |
|
142 |
|
c = wgetch(stdscr); |
|
143 |
|
strcat(pattern, (char*)(&c)); |
|
144 |
|
mvprintw(2, 0, "Pattern '%s'", pattern); |
|
145 |
|
mvprintw(3, 0, "Char '%d'", c); |
|
146 |
|
|
|
147 |
|
mvprintw(6, 0, "strlen() '%d'", strlen(pattern)); |
|
148 |
|
mvprintw(7, 0, "mbstowcs() '%d'", mbstowcs(NULL,pattern,0)); |
|
149 |
|
|
|
150 |
|
int i; |
|
151 |
|
int intSizeInBits = sizeof(int) * 8; |
|
152 |
|
char symbol[2] = {'0','1'}; |
|
153 |
|
char * binary = (char *)malloc(intSizeInBits + 1); |
|
154 |
|
memset(binary, 0, intSizeInBits + 1); |
|
155 |
|
for (i=0; i< intSizeInBits; i++) { |
|
156 |
|
binary[intSizeInBits-i-1] = symbol[(c>>i) & 0x01]; |
|
157 |
|
} |
|
158 |
|
mvprintw(10, 0, "bits: %s", binary); |
|
159 |
|
free(binary); |
|
160 |
|
|
|
161 |
|
mvprintw(11, 0, "high bit: %d %d ", 1<<7, 1<<7 & c); |
|
162 |
|
|
|
163 |
|
char cc=pattern[0]; |
|
164 |
|
i=0; |
|
165 |
|
int myStrlen=0; |
|
166 |
|
char isHighBitSet=0; |
|
167 |
|
while(cc) { |
|
168 |
|
print_char_bits(12, 9*i-8, pattern[i++]); |
|
169 |
|
cc=pattern[i]; |
|
170 |
|
|
|
171 |
|
if(1<<7 & pattern[i]) { |
|
172 |
|
if(isHighBitSet) { |
|
173 |
|
isHighBitSet=0; |
|
174 |
|
myStrlen++; |
|
175 |
|
} else { |
|
176 |
|
isHighBitSet=1; |
|
177 |
|
} |
|
178 |
|
} else { |
|
179 |
|
myStrlen++; |
|
180 |
|
} |
|
181 |
|
} |
|
182 |
|
|
|
183 |
|
mvprintw(14, 0, "mystrlen(): %d ", myStrlen); |
|
184 |
|
} |
185 |
185 |
|
|
186 |
186 |
clear(); |
clear(); |
187 |
187 |
refresh(); |
refresh(); |
|
... |
... |
void getch_with_counter_curses() { |
190 |
190 |
} |
} |
191 |
191 |
|
|
192 |
192 |
void done() { |
void done() { |
193 |
|
printf("\n\n"); |
|
|
193 |
|
printf("\n\n"); |
194 |
194 |
} |
} |
195 |
195 |
|
|
196 |
196 |
int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
|
... |
... |
int main(int argc, char *argv[]) |
203 |
203 |
//get_string_length(); |
//get_string_length(); |
204 |
204 |
//loop_string(); |
//loop_string(); |
205 |
205 |
|
|
206 |
|
getch_with_counter_curses(); |
|
207 |
|
done(); |
|
|
206 |
|
getch_with_counter_curses(); |
|
207 |
|
done(); |
208 |
208 |
} |
} |