+static void cut_line_by_fields(char *line)
+{
+ int c, f;
+ int ndelim = -1; /* zero-based / one-based problem */
+ int nfields_printed = 0;
+ char *field = NULL;
+ char d[2] = { delim, 0 };
+ char *printed;
+
+ /* test the easy case first: does this line contain any delimiters? */
+ if (strchr(line, delim) == NULL) {
+ if (!supress_non_delimited_lines)
+ puts(line);
+ return;
+ }
+
+ /* set up a list so we can keep track of what's been printed */
+ printed = xcalloc(strlen(line), sizeof(char));
+
+ /* process each list on this line, for as long as we've got a line to process */
+ for (c = 0; c < nlists && line; c++) {
+ f = cut_lists[c].startpos;
+ do {
+
+ /* find the field we're looking for */
+ while (line && ndelim < f) {
+ field = strsep(&line, d);
+ ndelim++;
+ }
+
+ /* we found it, and it hasn't been printed yet */
+ if (field && ndelim == f && !printed[ndelim]) {
+ /* if this isn't our first time through, we need to print the
+ * delimiter after the last field that was printed */
+ if (nfields_printed > 0)
+ putchar(delim);
+ fputs(field, stdout);
+ printed[ndelim] = 'X';
+ nfields_printed++;
+ }
+
+ f++;
+
+ /* keep going as long as we have a line to work with, this is a
+ * list, and we're not at the end of that list */
+ } while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos);
+ }
+
+ /* if we printed anything at all, we need to finish it with a newline cuz
+ * we were handed a chomped line */
+ putchar('\n');
+
+ free(printed);
+}
+
+
+static void cut_file_by_lines(const char *line, unsigned int linenum)
+{
+ static int c = 0;
+ static int l = -1;
+
+ /* I can't initialize this above cuz the "initializer isn't
+ * constant" *sigh* */
+ if (l == -1)
+ l = cut_lists[c].startpos;
+
+ /* get out if we have no more lists to process or if the lines are lower
+ * than what we're interested in */
+ if (c >= nlists || linenum < l)
+ return;
+
+ /* if the line we're looking for is lower than the one we were passed, it
+ * means we displayed it already, so move on */
+ while (l < linenum) {
+ l++;
+ /* move on to the next list if we're at the end of this one */
+ if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) {
+ c++;
+ /* get out if there's no more lists to process */
+ if (c >= nlists)
+ return;
+ l = cut_lists[c].startpos;
+ /* get out if the current line is lower than the one we just became
+ * interested in */
+ if (linenum < l)
+ return;