enum LOCATION_LENGTH, LOCATION_CURRENT_LINE, LOCATION_ARRAY, LOCATION_MODE; enum MODE_PRINT, MODE_NO_PRINT; define DATA_SIZE=4; range(start, stop) { local i; local sign; local tab; if (start > stop) sign = 0 - 1; else sign = 0 + 1; tab = galloc((stop - start) * sign + 1 + (start == stop)); if (tab == NULL) return NULL; i = 0; loop { [tab + i + 1] = start + (i * sign); if (start + (i * sign) == stop) break; i++; } [tab] = i + (start == stop); return tab; } get_number(data, str) { local ranges; local start = 0 -1; local stop = 0 -1; if ([[str]] == '%') { ranges = range(0, [data + LOCATION_LENGTH]); [str] = [str] + 1; } else { loop { if ([[str]] == '$') { if (start == 0 - 1) start = [data + LOCATION_LENGTH] - 1; else stop = [data + LOCATION_LENGTH] - 1; [str] = [str] + 1; } else if (isdigit([[str]])) { if (start == 0 - 1) start = aton([str]) - 1; else stop = aton([str]) - 1; loop { if (isdigit([[str]]) == 0) break; [str] = [str] + 1; } } else break; if ((start != 0 - 1 & stop != 0 - 1) | [[str]] == ',') [str] = [str] + 1; else break; } if (start != 0 - 1) { if (stop != 0 - 1) ranges = range(start, stop); else ranges = range(start, start); } else ranges = range([data + LOCATION_CURRENT_LINE], [data + LOCATION_CURRENT_LINE]); } return ranges; } parsing(data, cmd_ptr, ranges_ptr) { local input; local tmp; local i; local line_application; input = get_input(data, "(default)", NULL); if (input == NULL) return 1; if (strcmp(input, ".") == 0) { free(input); [cmd_ptr] = strdup("p"); return [cmd_ptr] == NULL; } tmp = input; [ranges_ptr] = get_number(data, &tmp); if (strcmp(tmp, "") == 0) [cmd_ptr] = strdup("p"); else [cmd_ptr] = strdup(tmp); free(input); if ([cmd_ptr] == NULL) return 1; i = 0; loop { if ([[ranges_ptr]] == i) break; [[ranges_ptr] + i + 1] = [[[data + LOCATION_ARRAY] + [[ranges_ptr] + i + 1]] + MAP_KEY]; i++; } } global id=0; main() { local data; local cmd; local ranges; local i; data = galloc(DATA_SIZE); if (data == NULL) return 1; [data + LOCATION_MODE] = 0; [data + LOCATION_CURRENT_LINE] = 0 - 1; [data + LOCATION_LENGTH] = 0; [data + LOCATION_ARRAY]; [data + LOCATION_ARRAY] = galloc(2); if ([data + LOCATION_ARRAY] == NULL) { free(data); return 1; } [[data + LOCATION_ARRAY] + MAP_KEY] = id++; [[data + LOCATION_ARRAY] + MAP_VALUE] = galloc(0); if ([[data + LOCATION_ARRAY] + MAP_VALUE] == NULL) { free([data + LOCATION_ARRAY]); free(data); return 1; } loop { if (parsing(data, &cmd, &ranges)) return 1; i = 0; loop { if (i == [ranges]) break; [data + LOCATION_CURRENT_LINE] = get_line_index_by_id(data, [ranges + 1 + i]); if (cmd != NULL) { if (strcmp(cmd, "a") == 0) cmd_add(data, NULL); else if (strcmp(cmd, "p") == 0) cmd_print(data, NULL); else if (strcmp(cmd, "n") == 0) cmd_numbered(data, NULL); else if (strcmp(cmd, "d") == 0) cmd_delete(data, NULL); else if (strcmp(cmd, "h") == 0) cmd_help(data, NULL); else if (strcmp(cmd, "w") == 0) cmd_write(data, NULL); else error(data, "cmd not foud"); free(cmd); } i++; } free(ranges); } }