summary refs log tree commit diff stats
path: root/tests/trmacros/trmacros_various2.nim
blob: 257ee8ba66105bcacc3c2bc7a6215a7d076c3b9a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
discard """
output: '''
0
-2
48
hel
lo
my awesome concat
'''
"""


block tnoalias2:
  # bug #206
  template optimizeOut{testFunc(a, b)}(a: int, b: int{alias}): untyped = 0

  proc testFunc(a, b: int): int = result = a + b
  var testVar = 1
  echo testFunc(testVar, testVar)


  template ex{a = b + c}(a : int{noalias}, b, c : int) =
    a = b
    inc a, b
    echo "came here"

  var x = 5
  x = x + x



block tpartial:
  proc p(x, y: int; cond: bool): int =
    result = if cond: x + y else: x - y

  template optPTrue{p(x, y, true)}(x, y): untyped = x - y
  template optPFalse{p(x, y, false)}(x, y): untyped = x + y

  echo p(2, 4, true)



block tpatterns:
  template optZero{x+x}(x: int): int = x*3
  template andthen{`*`(x,3)}(x: int): int = x*4
  template optSubstr1{x = substr(x, a, b)}(x: string, a, b: int) = setlen(x, b+1)

  var y = 12
  echo y+y

  var s: array[0..2, string]
  s[0] = "hello"
  s[0] = substr(s[0], 0, 2)

  echo s[0]

  # Test varargs matching
  proc someVarargProc(k: varargs[string]) = doAssert(false) # this should not get called
  template someVarargProcSingleArg{someVarargProc([a])}(a: string) = echo a
  someVarargProc("lo")



block tstar:
  var
    calls = 0

  proc `&&`(s: varargs[string]): string =
    result = s[0]
    for i in 1..len(s)-1: result.add s[i]
    inc calls

  template optConc{ `&&` * a }(a: string): string = &&a

  let space = " "
  echo "my" && (space & "awe" && "some " ) && "concat"

  # check that it's been optimized properly:
  doAssert calls == 1

# bug #7524
template in_to_out(typIn, typOut: typedesc) =
  proc to_out(x: typIn{lit}): typOut = result = ord(x)

# Generating the proc via template doesn't work
in_to_out(char, int)

# This works
proc to_out2(x: char{lit}): int = result = ord(x)
="w"> if (response < 0) { printf("Couldn't connect to %s news server, try again later.\n", server); exit(1); } if (handle_server_response(response, server) < 0 || response == OK_NOPOST) { close_server(); exit(1); } put_server("POST"); (void) get_server(line, sizeof(line)); if (*line != CHAR_CONT) { if (atoi(line) == ERR_NOPOST) { close_server(); fprintf(stderr, "Sorry, you can't post from this machine.\n"); exit(1); } else { close_server(); fprintf(stderr, "Remote error: %s\n", line); exit(1); } } in_header = 1; seen_header = 0; seen_fromline = 0; while (fgets(s, sizeof(s), stdin) != NULL) { if ((cp = strchr(s, '\n')) != NULL) *cp = '\0'; if (s[0] == '.') /* Single . is eof, so put in extra one */ (void) fputc('.', ser_wr_fp); if (in_header && strneql(s, "From:", sizeof("From:")-1)) { seen_header = 1; seen_fromline = 1; } if (in_header && s[0] == '\0') { if (seen_header) { in_header = 0; if (!seen_fromline) gen_frompath(); } else { continue; } } else if (in_header) { if (valid_header(s)) seen_header = 1; else continue; } fprintf(ser_wr_fp, "%s\r\n", s); } append_signature(); fprintf(ser_wr_fp, ".\r\n"); (void) fflush(ser_wr_fp); (void) get_server(line, sizeof(line)); if (*line != CHAR_OK) { if (atoi(line) == ERR_POSTFAIL) { close_server(); printf("Article not accepted by server; not posted.\n"); for (cp = line + 4; *cp && *cp != '\r'; cp++) if (*cp == '\\') putchar('\n'); else putchar(*cp); exit(1); } else { close_server(); fprintf(stderr, "Remote error: %s\n", line); exit(1); } } /* * Close server sends the server a * "quit" command for us, which is why we don't send it. */ close_server(); exit(0); } /* * append_signature -- append the person's .signature file if * they have one. Limit .signature to MAX_SIGNATURE lines. * The rn-style DOTDIR environmental variable is used if present. */ append_signature() { char line[256], sigfile[256]; char *cp; struct passwd *passwd; FILE *fp; char *index(), *getenv(); int count = 0; char *dotdir; passwd = getpwuid(getuid()); if (passwd == NULL) return; #ifdef DO_DOTDIR if ((dotdir = getenv("DOTDIR")) == NULL) #endif { dotdir = passwd->pw_dir; } if (dotdir[0] == '~') { (void) strcpy(sigfile, passwd->pw_dir); (void) strcat(sigfile, &dotdir[1]); } else { (void) strcpy(sigfile, dotdir); } (void) strcat(sigfile, "/"); (void) strcat(sigfile, ".signature"); #ifdef DEBUG fprintf(stderr,"sigfile = '%s'\n", sigfile); #endif fp = fopen(sigfile, "r"); if (fp == NULL) return; #ifdef DEBUG fprintf(stderr,"sigfile opened OK\n"); #endif fprintf(ser_wr_fp, "--\r\n"); while (fgets(line, sizeof (line), fp)) { count++; if (count > MAX_SIGNATURE) { fprintf(stderr, "Warning: .signature files should be no longer than %d lines.\n", MAX_SIGNATURE); fprintf(stderr, "(Only %d lines of your .signature were posted.)\n", MAX_SIGNATURE); break; } if (cp = index(line, '\n')) *cp = '\0'; fprintf(ser_wr_fp, "%s\r\n", line); } (void) fclose(fp); #ifdef DEBUG printf(".signature appended (from %s)\n", sigfile); #endif } /* * gen_frompath -- generate From: and Path: lines, in the form * * From: user@host.domain (full_name) * Path: host!user * * This routine should only be called if the message doesn't have * a From: line in it. */ gen_frompath() { char *full_name; char *cp; struct passwd *passwd; char *index(), *getenv(); passwd = getpwuid(getuid()); full_name = getenv("NAME"); if (full_name == NULL) { full_name = passwd->pw_gecos; if ((cp = index(full_name, ','))) *cp = '\0'; } #ifdef DOMAIN #ifdef HIDDENNET fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, DOMAIN); #else /* HIDDENNET */ /* A heuristic to see if we should tack on a domain */ cp = index(host_name, '.'); if (cp) fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, host_name); else fprintf(ser_wr_fp, "From: %s@%s.%s (", passwd->pw_name, host_name, DOMAIN); #endif /* HIDDENNET */ #else fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, host_name); #endif for (cp = full_name; *cp != '\0'; ++cp) if (*cp != '&') putc(*cp, ser_wr_fp); else { /* Stupid & hack. God damn it. */ putc(toupper(passwd->pw_name[0]), ser_wr_fp); fprintf(ser_wr_fp, passwd->pw_name+1); } fprintf(ser_wr_fp, ")\r\n"); #ifdef HIDDENNET /* Only the login name - nntp server will add uucp name */ fprintf(ser_wr_fp, "Path: %s\r\n", passwd->pw_name); #else /* HIDDENNET */ fprintf(ser_wr_fp, "Path: %s!%s\r\n", host_name, passwd->pw_name); #endif /* HIDDENNET */ } /* * strneql -- determine if two strings are equal in the first n * characters, ignoring case. * * Parameters: "a" and "b" are the pointers * to characters to be compared. * "n" is the number of characters to compare. * * Returns: 1 if the strings are equal, 0 otherwise. * * Side effects: None. */ strneql(a, b, n) register char *a, *b; int n; { char lower(); while (n && lower(*a) == lower(*b)) { if (*a == '\0') return (1); a++; b++; n--; } if (n) return (0); else return (1); } /* * lower -- convert a character to lower case, if it's * upper case. * * Parameters: "c" is the character to be * converted. * * Returns: "c" if the character is not * upper case, otherwise the lower * case eqivalent of "c". * * Side effects: None. */ char lower(c) register char c; { if (isascii(c) && isupper(c)) c = c - 'A' + 'a'; return(c); } /* * valid_header -- determine if a line is a valid header line * * Parameters: "h" is the header line to be checked. * * Returns: 1 if valid, 0 otherwise * * Side Effects: none * */ int valid_header(h) register char *h; { char *index(); char *colon, *space; /* * blank or tab in first position implies this is a continuation header */ if (h[0] == ' ' || h[0] == '\t') return (1); /* * just check for initial letter, colon, and space to make * sure we discard only invalid headers */ colon = index(h, ':'); space = index(h, ' '); if (isalpha(h[0]) && colon && space == colon + 1) return (1); /* * anything else is a bad header -- it should be ignored */ return (0); }