gen: don't remove the last return jump
[neatcc.git] / ncc.c
blob5da7497764feca61d32d1dcc1fc59d02ca547b78
1 /*
2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This file is released under GNU GPL version 2.
7 */
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include "gen.h"
16 #include "tok.h"
17 #include "out.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
23 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
24 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
26 #define T_ARRAY 0x01
27 #define T_STRUCT 0x02
28 #define T_FUNC 0x04
30 #define F_INIT 0x01
31 #define F_STATIC 0x02
32 #define F_EXTERN 0x04
34 struct type {
35 unsigned bt;
36 unsigned flags;
37 int ptr;
38 int id; /* for structs, functions and arrays */
39 int addr; /* the address is passed to gen.c; deref for value */
42 /* type stack */
43 static struct type ts[MAXTMP];
44 static int nts;
46 static void ts_push_bt(unsigned bt)
48 ts[nts].ptr = 0;
49 ts[nts].flags = 0;
50 ts[nts].addr = 0;
51 ts[nts++].bt = bt;
54 static void ts_push(struct type *t)
56 struct type *d = &ts[nts++];
57 memcpy(d, t, sizeof(*t));
60 static void ts_push_addr(struct type *t)
62 ts_push(t);
63 ts[nts - 1].addr = 1;
66 static void ts_pop(struct type *type)
68 nts--;
69 if (type)
70 *type = ts[nts];
73 void err(char *msg)
75 char err[1 << 7];
76 int len = cpp_loc(err, tok_addr());
77 strcpy(err + len, msg);
78 die(err);
81 struct name {
82 char name[NAMELEN];
83 char elfname[NAMELEN]; /* local elf name for static variables in function */
84 struct type type;
85 long addr; /* local stack offset, global data addr, struct offset */
88 static struct name locals[MAXLOCALS];
89 static int nlocals;
90 static struct name globals[MAXGLOBALS];
91 static int nglobals;
93 static void local_add(struct name *name)
95 if (nlocals >= MAXLOCALS)
96 err("nomem: MAXLOCALS reached!\n");
97 memcpy(&locals[nlocals++], name, sizeof(*name));
100 static int global_find(char *name)
102 int i;
103 for (i = 0; i < nglobals; i++)
104 if (!strcmp(name, globals[i].name))
105 return i;
106 return -1;
109 static void global_add(struct name *name)
111 int found = global_find(name->name);
112 int i = found == -1 ? nglobals++ : found;
113 if (nglobals >= MAXGLOBALS)
114 err("nomem: MAXGLOBALS reached!\n");
115 memcpy(&globals[i], name, sizeof(*name));
118 #define MAXENUMS (1 << 10)
120 static struct enumval {
121 char name[NAMELEN];
122 int n;
123 } enums[MAXENUMS];
124 static int nenums;
126 static void enum_add(char *name, int val)
128 struct enumval *ev = &enums[nenums++];
129 if (nenums >= MAXENUMS)
130 err("nomem: MAXENUMS reached!\n");
131 strcpy(ev->name, name);
132 ev->n = val;
135 static int enum_find(int *val, char *name)
137 int i;
138 for (i = nenums - 1; i >= 0; --i)
139 if (!strcmp(name, enums[i].name)) {
140 *val = enums[i].n;
141 return 0;
143 return 1;
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo {
149 char name[NAMELEN];
150 struct type type;
151 } typedefs[MAXTYPEDEFS];
152 static int ntypedefs;
154 static void typedef_add(char *name, struct type *type)
156 struct typdefinfo *ti = &typedefs[ntypedefs++];
157 if (ntypedefs >= MAXTYPEDEFS)
158 err("nomem: MAXTYPEDEFS reached!\n");
159 strcpy(ti->name, name);
160 memcpy(&ti->type, type, sizeof(*type));
163 static int typedef_find(char *name)
165 int i;
166 for (i = ntypedefs - 1; i >= 0; --i)
167 if (!strcmp(name, typedefs[i].name))
168 return i;
169 return -1;
172 #define MAXARRAYS (1 << 10)
174 static struct array {
175 struct type type;
176 int n;
177 } arrays[MAXARRAYS];
178 static int narrays;
180 static int array_add(struct type *type, int n)
182 struct array *a = &arrays[narrays++];
183 if (narrays >= MAXARRAYS)
184 err("nomem: MAXARRAYS reached!\n");
185 memcpy(&a->type, type, sizeof(*type));
186 a->n = n;
187 return a - arrays;
190 static void array2ptr(struct type *t)
192 if (t->flags & T_ARRAY && !t->ptr) {
193 memcpy(t, &arrays[t->id].type, sizeof(*t));
194 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return LONGSZ;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static void ts_de(int deref)
278 struct type *t = &ts[nts - 1];
279 if (deref && t->addr && (!(t->flags & T_ARRAY) || (t->ptr)))
280 o_deref(TYPE_BT(t));
281 t->addr = 0;
284 static void ts_pop_de(struct type *t)
286 struct type de;
287 if (!t)
288 t = &de;
289 ts_pop(t);
290 array2ptr(t);
291 if (t->addr && !(t->flags & T_FUNC))
292 o_deref(TYPE_BT(t));
293 t->addr = 0;
296 static void ts_pop_de2(struct type *t1, struct type *t2)
298 ts_pop_de(t1);
299 o_tmpswap();
300 ts_pop_de(t2);
301 o_tmpswap();
304 static int tok_jmp(int tok)
306 if (tok_see() != tok)
307 return 1;
308 tok_get();
309 return 0;
312 static void tok_expect(int tok)
314 if (tok_get() != tok)
315 err("syntax error\n");
318 static unsigned bt_op(unsigned bt1, unsigned bt2)
320 unsigned s1 = BT_SZ(bt1);
321 unsigned s2 = BT_SZ(bt2);
322 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
325 static void ts_binop(int op)
327 struct type t1, t2;
328 int bt;
329 ts_pop_de2(&t1, &t2);
330 if (op == O_DIV || op == O_MOD)
331 bt = TYPE_BT(&t2);
332 else
333 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
334 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
335 ts_push_bt(bt);
338 static void ts_addop(int op)
340 struct type t1, t2;
341 ts_pop_de2(&t1, &t2);
342 if (!t1.ptr && !t2.ptr) {
343 o_bop(op);
344 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
345 return;
347 if (t1.ptr && !t2.ptr)
348 o_tmpswap();
349 if (!t1.ptr && t2.ptr)
350 if (type_szde(&t2) > 1) {
351 o_num(type_szde(&t2));
352 o_bop(O_MUL);
354 if (t1.ptr && !t2.ptr)
355 o_tmpswap();
356 o_bop(op);
357 if (t1.ptr && t2.ptr) {
358 int sz = type_szde(&t1);
359 if (sz > 1) {
360 o_num(sz);
361 o_bop(O_DIV);
363 ts_push_bt(4 | BT_SIGNED);
364 } else {
365 ts_push(t1.ptr ? &t1 : &t2);
369 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
370 #define MIN(a, b) ((a) < (b) ? (a) : (b))
372 static int type_alignment(struct type *t)
374 if (t->flags & T_ARRAY && !t->ptr)
375 return type_alignment(&arrays[t->id].type);
376 if (t->flags & T_STRUCT && !t->ptr)
377 return type_alignment(&structs[t->id].fields[0].type);
378 return MIN(LONGSZ, type_totsz(t));
381 static void structdef(void *data, struct name *name, unsigned flags)
383 struct structinfo *si = data;
384 if (si->isunion) {
385 name->addr = 0;
386 if (si->size < type_totsz(&name->type))
387 si->size = type_totsz(&name->type);
388 } else {
389 struct type *t = &name->type;
390 int alignment = type_alignment(t);
391 if (t->flags & T_ARRAY && !t->ptr)
392 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
393 si->size = ALIGN(si->size, alignment);
394 name->addr = si->size;
395 si->size += type_totsz(&name->type);
397 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
400 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
402 static int struct_create(char *name, int isunion)
404 int id = struct_find(name, isunion);
405 struct structinfo *si = &structs[id];
406 tok_expect('{');
407 while (tok_jmp('}')) {
408 readdefs(structdef, si);
409 tok_expect(';');
411 return id;
414 static void readexpr(void);
416 static void enum_create(void)
418 long n = 0;
419 tok_expect('{');
420 while (tok_jmp('}')) {
421 char name[NAMELEN];
422 tok_expect(TOK_NAME);
423 strcpy(name, tok_id());
424 if (!tok_jmp('=')) {
425 readexpr();
426 ts_pop(NULL);
427 if (o_popnum(&n))
428 err("const expr expected!\n");
430 enum_add(name, n++);
431 tok_jmp(',');
435 static int basetype(struct type *type, unsigned *flags)
437 int sign = 1;
438 int size = 4;
439 int done = 0;
440 int i = 0;
441 int isunion;
442 char name[NAMELEN] = "";
443 *flags = 0;
444 type->flags = 0;
445 type->ptr = 0;
446 type->addr = 0;
447 while (!done) {
448 switch (tok_see()) {
449 case TOK_STATIC:
450 *flags |= F_STATIC;
451 break;
452 case TOK_EXTERN:
453 *flags |= F_EXTERN;
454 break;
455 case TOK_VOID:
456 sign = 0;
457 size = 0;
458 done = 1;
459 break;
460 case TOK_INT:
461 done = 1;
462 break;
463 case TOK_CHAR:
464 size = 1;
465 done = 1;
466 break;
467 case TOK_SHORT:
468 size = 2;
469 break;
470 case TOK_LONG:
471 size = LONGSZ;
472 break;
473 case TOK_SIGNED:
474 break;
475 case TOK_UNSIGNED:
476 sign = 0;
477 break;
478 case TOK_UNION:
479 case TOK_STRUCT:
480 isunion = tok_get() == TOK_UNION;
481 if (!tok_jmp(TOK_NAME))
482 strcpy(name, tok_id());
483 if (tok_see() == '{')
484 type->id = struct_create(name, isunion);
485 else
486 type->id = struct_find(name, isunion);
487 type->flags |= T_STRUCT;
488 type->bt = LONGSZ;
489 return 0;
490 case TOK_ENUM:
491 tok_get();
492 tok_jmp(TOK_NAME);
493 if (tok_see() == '{')
494 enum_create();
495 type->bt = 4 | BT_SIGNED;
496 return 0;
497 default:
498 if (tok_see() == TOK_NAME) {
499 int id = typedef_find(tok_id());
500 if (id != -1) {
501 tok_get();
502 memcpy(type, &typedefs[id].type,
503 sizeof(*type));
504 return 0;
507 if (!i)
508 return 1;
509 done = 1;
510 continue;
512 i++;
513 tok_get();
515 type->bt = size | (sign ? BT_SIGNED : 0);
516 return 0;
519 static int readname(struct type *main, char *name,
520 struct type *base, unsigned flags);
522 static int readtype(struct type *type)
524 return readname(type, NULL, NULL, 0);
527 static void readptrs(struct type *type)
529 while (!tok_jmp('*')) {
530 type->ptr++;
531 if (!type->bt)
532 type->bt = 1;
536 /* used to differenciate labels from case and cond exprs */
537 static int ncexpr;
538 static int caseexpr;
540 static void readpre(void);
542 static char *tmp_str(char *buf, int len)
544 static char name[NAMELEN];
545 static int id;
546 void *dat;
547 sprintf(name, "__neatcc.s%d", id++);
548 dat = dat_dat(name, len, 0);
549 memcpy(dat, buf, len);
550 return name;
553 static void readprimary(void)
555 int i;
556 if (!tok_jmp(TOK_NUM)) {
557 long n;
558 int bt = tok_num(&n);
559 ts_push_bt(bt);
560 o_num(n);
561 return;
563 if (!tok_jmp(TOK_STR)) {
564 struct type t;
565 char buf[BUFSIZE];
566 int len;
567 t.bt = 1 | BT_SIGNED;
568 t.ptr = 1;
569 t.addr = 0;
570 t.flags = 0;
571 ts_push(&t);
572 len = tok_str(buf);
573 o_sym(tmp_str(buf, len));
574 return;
576 if (!tok_jmp(TOK_NAME)) {
577 struct name unkn = {""};
578 char *name = unkn.name;
579 int n;
580 strcpy(name, tok_id());
581 /* don't search for labels here */
582 if (!ncexpr && !caseexpr && tok_see() == ':')
583 return;
584 for (i = nlocals - 1; i >= 0; --i) {
585 struct type *t = &locals[i].type;
586 if (!strcmp(locals[i].name, name)) {
587 o_local(locals[i].addr);
588 ts_push_addr(t);
589 return;
592 if ((n = global_find(name)) != -1) {
593 struct name *g = &globals[n];
594 struct type *t = &g->type;
595 char *elfname = *g->elfname ? g->elfname : g->name;
596 o_sym(elfname);
597 ts_push_addr(t);
598 return;
600 if (!enum_find(&n, name)) {
601 ts_push_bt(4 | BT_SIGNED);
602 o_num(n);
603 return;
605 if (tok_see() != '(')
606 err("unknown symbol\n");
607 global_add(&unkn);
608 ts_push_bt(LONGSZ);
609 o_sym(unkn.name);
610 return;
612 if (!tok_jmp('(')) {
613 struct type t;
614 if (!readtype(&t)) {
615 struct type o;
616 tok_expect(')');
617 readpre();
618 ts_pop_de(&o);
619 ts_push(&t);
620 if (!t.ptr || !o.ptr)
621 o_cast(TYPE_BT(&t));
622 } else {
623 readexpr();
624 tok_expect(')');
626 return;
630 static void arrayderef(void)
632 struct type t;
633 int sz;
634 ts_pop_de(NULL);
635 ts_pop(&t);
636 if (!(t.flags & T_ARRAY) && t.addr) {
637 o_tmpswap();
638 o_deref(TYPE_BT(&t));
639 o_tmpswap();
641 array2ptr(&t);
642 t.ptr--;
643 sz = type_totsz(&t);
644 t.addr = 1;
645 if (sz > 1) {
646 o_num(sz);
647 o_bop(O_MUL);
649 o_bop(O_ADD);
650 ts_push(&t);
653 static void inc_post(int op)
655 struct type t = ts[nts - 1];
656 /* pushing the value before inc */
657 o_tmpcopy();
658 ts_de(1);
659 o_load();
660 o_tmpswap();
662 /* increment by 1 or pointer size */
663 o_tmpcopy();
664 ts_push(&t);
665 ts_pop_de(&t);
666 o_num(t.ptr > 0 ? type_szde(&t) : 1);
667 o_bop(op);
669 /* assign back */
670 o_assign(TYPE_BT(&t));
671 o_tmpdrop(1);
674 static void readfield(void)
676 struct name *field;
677 struct type t;
678 tok_expect(TOK_NAME);
679 ts_pop(&t);
680 array2ptr(&t);
681 field = struct_field(t.id, tok_id());
682 if (field->addr) {
683 o_num(field->addr);
684 o_bop(O_ADD);
686 ts_push_addr(&field->type);
689 #define MAXFUNCS (1 << 10)
691 static struct funcinfo {
692 struct type args[MAXFIELDS];
693 struct type ret;
694 int nargs;
695 } funcs[MAXFUNCS];
696 static int nfuncs;
698 static int func_create(struct type *ret, struct name *args, int nargs)
700 struct funcinfo *fi = &funcs[nfuncs++];
701 int i;
702 if (nfuncs >= MAXFUNCS)
703 err("nomem: MAXFUNCS reached!\n");
704 memcpy(&fi->ret, ret, sizeof(*ret));
705 for (i = 0; i < nargs; i++)
706 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
707 fi->nargs = nargs;
708 return fi - funcs;
711 static void readcall(void)
713 struct type t;
714 struct funcinfo *fi;
715 int argc = 0;
716 ts_pop(&t);
717 if (t.flags & T_FUNC && t.ptr > 0)
718 o_deref(LONGSZ);
719 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
720 if (tok_see() != ')') {
721 do {
722 readexpr();
723 ts_pop_de(NULL);
724 argc++;
725 } while (!tok_jmp(','));
727 tok_expect(')');
728 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
729 if (fi) {
730 if (TYPE_BT(&fi->ret))
731 o_cast(TYPE_BT(&fi->ret));
732 ts_push(&fi->ret);
733 } else {
734 ts_push_bt(4 | BT_SIGNED);
738 static void readpost(void)
740 readprimary();
741 while (1) {
742 if (!tok_jmp('[')) {
743 readexpr();
744 tok_expect(']');
745 arrayderef();
746 continue;
748 if (!tok_jmp('(')) {
749 readcall();
750 continue;
752 if (!tok_jmp(TOK2("++"))) {
753 inc_post(O_ADD);
754 continue;
756 if (!tok_jmp(TOK2("--"))) {
757 inc_post(O_SUB);
758 continue;
760 if (!tok_jmp('.')) {
761 readfield();
762 continue;
764 if (!tok_jmp(TOK2("->"))) {
765 ts_de(1);
766 readfield();
767 continue;
769 break;
773 static void inc_pre(int op)
775 struct type t;
776 readpre();
777 /* copy the destination */
778 o_tmpcopy();
779 ts_push(&ts[nts - 1]);
780 /* increment by 1 or pointer size */
781 ts_pop_de(&t);
782 o_num(t.ptr > 0 ? type_szde(&t) : 1);
783 o_bop(op);
784 /* assign the result */
785 o_assign(TYPE_BT(&t));
786 ts_de(0);
789 static void readpre(void)
791 if (!tok_jmp('&')) {
792 struct type type;
793 readpre();
794 ts_pop(&type);
795 if (!type.addr)
796 die("cannot use the address\n");
797 type.ptr++;
798 type.addr = 0;
799 ts_push(&type);
800 return;
802 if (!tok_jmp('*')) {
803 struct type t;
804 readpre();
805 ts_pop(&t);
806 array2ptr(&t);
807 if (!t.ptr)
808 err("dereferencing non-pointer\n");
809 if (t.addr)
810 o_deref(TYPE_BT(&t));
811 t.ptr--;
812 t.addr = 1;
813 ts_push(&t);
814 return;
816 if (!tok_jmp('!')) {
817 readpre();
818 ts_pop_de(NULL);
819 o_uop(O_LNOT);
820 ts_push_bt(4 | BT_SIGNED);
821 return;
823 if (!tok_jmp('-')) {
824 readpre();
825 ts_de(1);
826 o_uop(O_NEG);
827 return;
829 if (!tok_jmp('~')) {
830 readpre();
831 ts_de(1);
832 o_uop(O_NOT);
833 return;
835 if (!tok_jmp(TOK2("++"))) {
836 inc_pre(O_ADD);
837 return;
839 if (!tok_jmp(TOK2("--"))) {
840 inc_pre(O_SUB);
841 return;
843 if (!tok_jmp(TOK_SIZEOF)) {
844 struct type t;
845 int op = !tok_jmp('(');
846 if (readtype(&t)) {
847 o_nogen();
848 readexpr();
849 o_dogen();
850 ts_pop(&t);
851 o_tmpdrop(1);
853 ts_push_bt(4);
854 o_num(type_totsz(&t));
855 if (op)
856 tok_expect(')');
857 return;
859 readpost();
862 static void readmul(void)
864 readpre();
865 while (1) {
866 if (!tok_jmp('*')) {
867 readpre();
868 ts_binop(O_MUL);
869 continue;
871 if (!tok_jmp('/')) {
872 readpre();
873 ts_binop(O_DIV);
874 continue;
876 if (!tok_jmp('%')) {
877 readpre();
878 ts_binop(O_MOD);
879 continue;
881 break;
885 static void readadd(void)
887 readmul();
888 while (1) {
889 if (!tok_jmp('+')) {
890 readmul();
891 ts_addop(O_ADD);
892 continue;
894 if (!tok_jmp('-')) {
895 readmul();
896 ts_addop(O_SUB);
897 continue;
899 break;
903 static void shift(int op)
905 struct type t;
906 readadd();
907 ts_pop_de2(NULL, &t);
908 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
909 ts_push_bt(TYPE_BT(&t));
912 static void readshift(void)
914 readadd();
915 while (1) {
916 if (!tok_jmp(TOK2("<<"))) {
917 shift(O_SHL);
918 continue;
920 if (!tok_jmp(TOK2(">>"))) {
921 shift(O_SHR);
922 continue;
924 break;
928 static void cmp(int op)
930 struct type t1, t2;
931 int bt;
932 readshift();
933 ts_pop_de2(&t1, &t2);
934 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
935 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
936 ts_push_bt(4 | BT_SIGNED);
939 static void readcmp(void)
941 readshift();
942 while (1) {
943 if (!tok_jmp('<')) {
944 cmp(O_LT);
945 continue;
947 if (!tok_jmp('>')) {
948 cmp(O_GT);
949 continue;
951 if (!tok_jmp(TOK2("<="))) {
952 cmp(O_LE);
953 continue;
955 if (!tok_jmp(TOK2(">="))) {
956 cmp(O_GE);
957 continue;
959 break;
963 static void eq(int op)
965 readcmp();
966 ts_pop_de2(NULL, NULL);
967 o_bop(op);
968 ts_push_bt(4 | BT_SIGNED);
971 static void readeq(void)
973 readcmp();
974 while (1) {
975 if (!tok_jmp(TOK2("=="))) {
976 eq(O_EQ);
977 continue;
979 if (!tok_jmp(TOK2("!="))) {
980 eq(O_NEQ);
981 continue;
983 break;
987 static void readbitand(void)
989 readeq();
990 while (!tok_jmp('&')) {
991 readeq();
992 ts_binop(O_AND);
996 static void readxor(void)
998 readbitand();
999 while (!tok_jmp('^')) {
1000 readbitand();
1001 ts_binop(O_XOR);
1005 static void readbitor(void)
1007 readxor();
1008 while (!tok_jmp('|')) {
1009 readxor();
1010 ts_binop(O_OR);
1014 #define MAXCOND (1 << 7)
1016 static void readand(void)
1018 long conds[MAXCOND];
1019 int nconds = 0;
1020 long passed;
1021 int i;
1022 readbitor();
1023 if (tok_see() != TOK2("&&"))
1024 return;
1025 o_fork();
1026 ts_pop_de(NULL);
1027 conds[nconds++] = o_jz(0);
1028 while (!tok_jmp(TOK2("&&"))) {
1029 readbitor();
1030 ts_pop_de(NULL);
1031 conds[nconds++] = o_jz(0);
1033 o_num(1);
1034 o_forkpush();
1035 passed = o_jmp(0);
1036 for (i = 0; i < nconds; i++)
1037 o_filljmp(conds[i]);
1038 o_num(0);
1039 o_forkpush();
1040 o_forkjoin();
1041 o_filljmp(passed);
1042 ts_push_bt(4 | BT_SIGNED);
1045 static void reador(void)
1047 long conds[MAXCOND];
1048 int nconds = 0;
1049 long failed;
1050 int i;
1051 readand();
1052 if (tok_see() != TOK2("||"))
1053 return;
1054 o_fork();
1055 ts_pop_de(NULL);
1056 conds[nconds++] = o_jnz(0);
1057 while (!tok_jmp(TOK2("||"))) {
1058 readand();
1059 ts_pop_de(NULL);
1060 conds[nconds++] = o_jnz(0);
1062 o_num(0);
1063 o_forkpush();
1064 failed = o_jmp(0);
1065 for (i = 0; i < nconds; i++)
1066 o_filljmp(conds[i]);
1067 o_num(1);
1068 o_forkpush();
1069 o_forkjoin();
1070 o_filljmp(failed);
1071 ts_push_bt(4 | BT_SIGNED);
1074 static int readcexpr_const(void)
1076 long c;
1077 if (o_popnum(&c))
1078 return -1;
1079 if (!c)
1080 o_nogen();
1081 reador();
1082 ts_pop(NULL);
1083 tok_expect(':');
1084 if (c) {
1085 o_nogen();
1086 } else {
1087 o_dogen();
1088 o_tmpdrop(1);
1090 reador();
1091 if (c) {
1092 o_dogen();
1093 o_tmpdrop(1);
1095 return 0;
1098 static void readcexpr(void)
1100 long l1, l2;
1101 reador();
1102 if (tok_jmp('?'))
1103 return;
1104 ncexpr++;
1105 ts_pop_de(NULL);
1106 o_fork();
1107 if (readcexpr_const()) {
1108 l1 = o_jz(0);
1109 reador();
1110 ts_de(1);
1111 o_forkpush();
1112 l2 = o_jmp(0);
1113 ts_pop(NULL);
1115 tok_expect(':');
1116 o_filljmp(l1);
1117 reador();
1118 ts_de(1);
1119 o_forkpush();
1120 o_forkjoin();
1121 o_filljmp(l2);
1123 ncexpr--;
1126 static void opassign(int op, int ptrop)
1128 struct type t = ts[nts - 1];
1129 o_tmpcopy();
1130 ts_push(&t);
1131 readexpr();
1132 ts_addop(op);
1133 o_assign(TYPE_BT(&ts[nts - 1]));
1134 ts_pop(NULL);
1135 ts_de(0);
1138 static void doassign(void)
1140 struct type t = ts[nts - 1];
1141 if (!t.ptr && t.flags & T_STRUCT) {
1142 ts_pop(NULL);
1143 o_num(type_totsz(&t));
1144 o_memcpy();
1145 } else {
1146 ts_pop_de(NULL);
1147 o_assign(TYPE_BT(&ts[nts - 1]));
1148 ts_de(0);
1152 static void readexpr(void)
1154 readcexpr();
1155 if (!tok_jmp('=')) {
1156 readexpr();
1157 doassign();
1158 return;
1160 if (!tok_jmp(TOK2("+="))) {
1161 opassign(O_ADD, 1);
1162 return;
1164 if (!tok_jmp(TOK2("-="))) {
1165 opassign(O_SUB, 1);
1166 return;
1168 if (!tok_jmp(TOK2("*="))) {
1169 opassign(O_MUL, 0);
1170 return;
1172 if (!tok_jmp(TOK2("/="))) {
1173 opassign(O_DIV, 0);
1174 return;
1176 if (!tok_jmp(TOK2("%="))) {
1177 opassign(O_MOD, 0);
1178 return;
1180 if (!tok_jmp(TOK3("<<="))) {
1181 opassign(O_SHL, 0);
1182 return;
1184 if (!tok_jmp(TOK3(">>="))) {
1185 opassign(O_SHR, 0);
1186 return;
1188 if (!tok_jmp(TOK3("&="))) {
1189 opassign(O_AND, 0);
1190 return;
1192 if (!tok_jmp(TOK3("|="))) {
1193 opassign(O_OR, 0);
1194 return;
1196 if (!tok_jmp(TOK3("^="))) {
1197 opassign(O_XOR, 0);
1198 return;
1202 static void readestmt(void)
1204 do {
1205 o_tmpdrop(-1);
1206 nts = 0;
1207 readexpr();
1208 } while (!tok_jmp(','));
1211 static void o_localoff(long addr, int off)
1213 o_local(addr);
1214 if (off) {
1215 o_num(off);
1216 o_bop(O_ADD);
1220 static struct type *innertype(struct type *t)
1222 if (t->flags & T_ARRAY && !t->ptr)
1223 return innertype(&arrays[t->id].type);
1224 return t;
1227 static void initexpr(struct type *t, int off, void *obj,
1228 void (*set)(void *obj, int off, struct type *t))
1230 if (tok_jmp('{')) {
1231 set(obj, off, t);
1232 return;
1234 if (!t->ptr && t->flags & T_STRUCT) {
1235 struct structinfo *si = &structs[t->id];
1236 int i;
1237 for (i = 0; i < si->nfields; i++) {
1238 struct name *field = &si->fields[i];
1239 if (!tok_jmp('.')) {
1240 tok_expect(TOK_NAME);
1241 field = struct_field(t->id, tok_id());
1242 tok_expect('=');
1244 initexpr(&field->type, off + field->addr, obj, set);
1245 if (tok_jmp(',') || tok_see() == '}')
1246 break;
1248 } else if (t->flags & T_ARRAY) {
1249 struct type *t_de = &arrays[t->id].type;
1250 int i;
1251 for (i = 0; ; i++) {
1252 long idx = i;
1253 struct type *it = t_de;
1254 if (!tok_jmp('[')) {
1255 readexpr();
1256 o_popnum(&idx);
1257 ts_pop(NULL);
1258 tok_expect(']');
1259 tok_expect('=');
1261 if (tok_see() != '{')
1262 it = innertype(t_de);
1263 initexpr(it, off + type_totsz(it) * idx, obj, set);
1264 if (tok_jmp(',') || tok_see() == '}')
1265 break;
1268 tok_expect('}');
1271 static void jumpbrace(void)
1273 int depth = 0;
1274 while (tok_see() != '}' || depth--)
1275 if (tok_get() == '{')
1276 depth++;
1277 tok_expect('}');
1280 static int initsize(void)
1282 long addr = tok_addr();
1283 int n = 0;
1284 if (!tok_jmp(TOK_STR)) {
1285 n = tok_str(NULL);
1286 tok_jump(addr);
1287 return n;
1289 o_nogen();
1290 tok_expect('{');
1291 while (tok_jmp('}')) {
1292 long idx = n;
1293 if (!tok_jmp('[')) {
1294 readexpr();
1295 o_popnum(&idx);
1296 ts_pop(NULL);
1297 tok_expect(']');
1298 tok_expect('=');
1300 if (n < idx + 1)
1301 n = idx + 1;
1302 while (tok_see() != '}' && tok_see() != ',')
1303 if (tok_get() == '{')
1304 jumpbrace();
1305 tok_jmp(',');
1307 o_dogen();
1308 tok_jump(addr);
1309 return n;
1312 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1314 static void globalinit(void *obj, int off, struct type *t)
1316 struct name *name = obj;
1317 char *elfname = *name->elfname ? name->elfname : name->name;
1318 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1319 struct type *t_de = &arrays[t->id].type;
1320 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1321 char buf[BUFSIZE];
1322 int len;
1323 tok_expect(TOK_STR);
1324 len = tok_str(buf);
1325 memcpy((void *) name->addr + off, buf, len);
1326 return;
1329 readexpr();
1330 o_datset(elfname, off, TYPE_BT(t));
1331 ts_pop(NULL);
1334 static void globaldef(void *data, struct name *name, unsigned flags)
1336 struct type *t = &name->type;
1337 char *elfname = *name->elfname ? name->elfname : name->name;
1338 int sz;
1339 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1340 if (~flags & F_EXTERN)
1341 arrays[t->id].n = initsize();
1342 sz = type_totsz(t);
1343 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1344 if (flags & F_INIT)
1345 name->addr = (long) dat_dat(elfname, sz, F_GLOBAL(flags));
1346 else
1347 dat_bss(elfname, sz, F_GLOBAL(flags));
1349 global_add(name);
1350 if (flags & F_INIT)
1351 initexpr(t, 0, name, globalinit);
1354 static void localinit(void *obj, int off, struct type *t)
1356 long addr = *(long *) obj;
1357 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1358 struct type *t_de = &arrays[t->id].type;
1359 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1360 char buf[BUFSIZE];
1361 int len;
1362 tok_expect(TOK_STR);
1363 len = tok_str(buf);
1364 o_localoff(addr, off);
1365 o_sym(tmp_str(buf, len));
1366 o_num(len);
1367 o_memcpy();
1368 o_tmpdrop(1);
1369 return;
1372 o_localoff(addr, off);
1373 ts_push(t);
1374 readexpr();
1375 doassign();
1376 ts_pop(NULL);
1377 o_tmpdrop(1);
1380 /* current function name */
1381 static char func_name[NAMELEN];
1383 static void localdef(void *data, struct name *name, unsigned flags)
1385 struct type *t = &name->type;
1386 if (flags & (F_STATIC | F_EXTERN)) {
1387 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1388 globaldef(data, name, flags);
1389 return;
1391 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1392 arrays[t->id].n = initsize();
1393 name->addr = o_mklocal(type_totsz(&name->type));
1394 local_add(name);
1395 if (flags & F_INIT) {
1396 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1397 o_local(name->addr);
1398 o_num(0);
1399 o_num(type_totsz(t));
1400 o_memset();
1401 o_tmpdrop(1);
1403 initexpr(t, 0, &name->addr, localinit);
1407 static void funcdef(char *name, struct type *type, struct name *args,
1408 int nargs, unsigned flags)
1410 struct name global = {""};
1411 int i;
1412 strcpy(global.name, name);
1413 strcpy(func_name, name);
1414 memcpy(&global.type, type, sizeof(*type));
1415 o_func_beg(name, F_GLOBAL(flags));
1416 global_add(&global);
1417 for (i = 0; i < nargs; i++) {
1418 args[i].addr = o_arg(i);
1419 local_add(&args[i]);
1423 static int readargs(struct name *args)
1425 int nargs = 0;
1426 tok_expect('(');
1427 while (tok_see() != ')') {
1428 if (!tok_jmp(TOK3("...")))
1429 break;
1430 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1431 array2ptr(&args[nargs].type);
1432 nargs++;
1433 if (tok_jmp(','))
1434 break;
1436 tok_expect(')');
1437 if (nargs == 1 && !TYPE_BT(&args[0].type))
1438 return 0;
1439 return nargs;
1442 static int readname(struct type *main, char *name,
1443 struct type *base, unsigned flags)
1445 struct type tpool[3];
1446 int npool = 0;
1447 struct type *type = &tpool[npool++];
1448 struct type *func = NULL;
1449 struct type *ret = NULL;
1450 int arsz[10];
1451 int nar = 0;
1452 int i;
1453 memset(tpool, 0, sizeof(tpool));
1454 if (name)
1455 *name = '\0';
1456 if (!base) {
1457 if (basetype(type, &flags))
1458 return 1;
1459 } else {
1460 memcpy(type, base, sizeof(*base));
1462 readptrs(type);
1463 if (!tok_jmp('(')) {
1464 ret = type;
1465 type = &tpool[npool++];
1466 func = type;
1467 readptrs(type);
1469 if (!tok_jmp(TOK_NAME) && name)
1470 strcpy(name, tok_id());
1471 while (!tok_jmp('[')) {
1472 long n = 0;
1473 if (tok_jmp(']')) {
1474 readexpr();
1475 ts_pop(NULL);
1476 if (o_popnum(&n))
1477 err("const expr expected\n");
1478 tok_expect(']');
1480 arsz[nar++] = n;
1482 for (i = nar - 1; i >= 0; i--) {
1483 type->id = array_add(type, arsz[i]);
1484 if (func && i == nar - 1)
1485 func = &arrays[type->id].type;
1486 type->flags = T_ARRAY;
1487 type->bt = LONGSZ;
1488 type->ptr = 0;
1490 if (func)
1491 tok_expect(')');
1492 if (tok_see() == '(') {
1493 struct name args[MAXARGS] = {{""}};
1494 int nargs = readargs(args);
1495 int fdef = !func;
1496 if (!func) {
1497 ret = type;
1498 type = &tpool[npool++];
1499 func = type;
1501 func->flags = T_FUNC;
1502 func->bt = LONGSZ;
1503 func->id = func_create(ret, args, nargs);
1504 if (fdef && tok_see() == '{') {
1505 funcdef(name, func, args, nargs, flags);
1506 return 1;
1509 memcpy(main, type, sizeof(*type));
1510 return 0;
1513 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1514 void *data)
1516 struct type base;
1517 unsigned base_flags;
1518 if (basetype(&base, &base_flags))
1519 return 1;
1520 while (tok_see() != ';' && tok_see() != '{') {
1521 struct name name = {{""}};
1522 unsigned flags = base_flags;
1523 if (readname(&name.type, name.name, &base, flags))
1524 break;
1525 if (!tok_jmp('='))
1526 flags |= F_INIT;
1527 def(data, &name, flags);
1528 tok_jmp(',');
1530 return 0;
1533 static void typedefdef(void *data, struct name *name, unsigned flags)
1535 typedef_add(name->name, &name->type);
1538 static void readstmt(void);
1540 #define MAXCASES (1 << 7)
1542 static void readswitch(void)
1544 int break_beg = nbreaks;
1545 long val_addr = o_mklocal(LONGSZ);
1546 long matched[MAXCASES];
1547 int nmatched = 0;
1548 struct type t;
1549 long next;
1550 int ref = 1;
1551 int i;
1552 tok_expect('(');
1553 readexpr();
1554 ts_pop_de(&t);
1555 o_local(val_addr);
1556 o_tmpswap();
1557 o_assign(TYPE_BT(&t));
1558 ts_de(0);
1559 o_tmpdrop(1);
1560 tok_expect(')');
1561 tok_expect('{');
1562 while (tok_jmp('}')) {
1563 int n = 0;
1564 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1565 if (n++ > 0)
1566 matched[nmatched++] = o_jmp(0);
1567 if (!ref++)
1568 o_filljmp(next);
1569 if (!tok_jmp(TOK_CASE)) {
1570 caseexpr = 1;
1571 readexpr();
1572 ts_pop_de(NULL);
1573 caseexpr = 0;
1574 o_local(val_addr);
1575 o_deref(TYPE_BT(&t));
1576 o_bop(O_EQ);
1577 next = o_jz(0);
1578 ref = 0;
1579 tok_expect(':');
1580 o_tmpdrop(1);
1581 continue;
1583 if (!tok_jmp(TOK_DEFAULT)) {
1584 tok_expect(':');
1585 continue;
1588 for (i = 0; i < nmatched; i++)
1589 o_filljmp(matched[i]);
1590 nmatched = 0;
1591 readstmt();
1593 o_rmlocal(val_addr, LONGSZ);
1594 if (!ref++)
1595 o_filljmp(next);
1596 break_fill(o_mklabel(), break_beg);
1599 #define MAXGOTO (1 << 10)
1601 static struct gotoinfo {
1602 char name[NAMELEN];
1603 long addr;
1604 } gotos[MAXGOTO];
1605 static int ngotos;
1607 static struct labelinfo {
1608 char name[NAMELEN];
1609 long addr;
1610 } labels[MAXGOTO];
1611 static int nlabels;
1613 static void goto_add(char *name)
1615 strcpy(gotos[ngotos].name, name);
1616 gotos[ngotos++].addr = o_jmp(0);
1619 static void label_add(char *name)
1621 strcpy(labels[nlabels].name, name);
1622 labels[nlabels++].addr = o_mklabel();
1625 static void goto_fill(void)
1627 int i, j;
1628 for (i = 0; i < ngotos; i++)
1629 for (j = 0; j < nlabels; j++)
1630 if (!strcmp(gotos[i].name, labels[j].name)) {
1631 o_filljmp2(gotos[i].addr, labels[j].addr);
1632 break;
1636 static void readstmt(void)
1638 o_tmpdrop(-1);
1639 nts = 0;
1640 if (!tok_jmp('{')) {
1641 int _nlocals = nlocals;
1642 int _nglobals = nglobals;
1643 int _nenums = nenums;
1644 int _ntypedefs = ntypedefs;
1645 int _nstructs = nstructs;
1646 int _nfuncs = nfuncs;
1647 int _narrays = narrays;
1648 while (tok_jmp('}'))
1649 readstmt();
1650 nlocals = _nlocals;
1651 nenums = _nenums;
1652 ntypedefs = _ntypedefs;
1653 nstructs = _nstructs;
1654 nfuncs = _nfuncs;
1655 narrays = _narrays;
1656 nglobals = _nglobals;
1657 return;
1659 if (!readdefs(localdef, NULL)) {
1660 tok_expect(';');
1661 return;
1663 if (!tok_jmp(TOK_TYPEDEF)) {
1664 readdefs(typedefdef, NULL);
1665 tok_expect(';');
1666 return;
1668 if (!tok_jmp(TOK_IF)) {
1669 long l1, l2;
1670 tok_expect('(');
1671 readexpr();
1672 tok_expect(')');
1673 ts_pop_de(NULL);
1674 l1 = o_jz(0);
1675 readstmt();
1676 if (!tok_jmp(TOK_ELSE)) {
1677 l2 = o_jmp(0);
1678 o_filljmp(l1);
1679 readstmt();
1680 o_filljmp(l2);
1681 } else {
1682 o_filljmp(l1);
1684 return;
1686 if (!tok_jmp(TOK_WHILE)) {
1687 long l1, l2;
1688 int break_beg = nbreaks;
1689 int continue_beg = ncontinues;
1690 l1 = o_mklabel();
1691 tok_expect('(');
1692 readexpr();
1693 tok_expect(')');
1694 ts_pop_de(NULL);
1695 l2 = o_jz(0);
1696 readstmt();
1697 o_jmp(l1);
1698 o_filljmp(l2);
1699 break_fill(o_mklabel(), break_beg);
1700 continue_fill(l1, continue_beg);
1701 return;
1703 if (!tok_jmp(TOK_DO)) {
1704 long l1, l2;
1705 int break_beg = nbreaks;
1706 int continue_beg = ncontinues;
1707 l1 = o_mklabel();
1708 readstmt();
1709 tok_expect(TOK_WHILE);
1710 tok_expect('(');
1711 l2 = o_mklabel();
1712 readexpr();
1713 ts_pop_de(NULL);
1714 o_jnz(l1);
1715 tok_expect(')');
1716 break_fill(o_mklabel(), break_beg);
1717 continue_fill(l2, continue_beg);
1718 return;
1720 if (!tok_jmp(TOK_FOR)) {
1721 long l_check, l_jump, j_fail, j_pass;
1722 int break_beg = nbreaks;
1723 int continue_beg = ncontinues;
1724 int has_cond = 0;
1725 tok_expect('(');
1726 if (tok_see() != ';')
1727 readestmt();
1728 tok_expect(';');
1729 l_check = o_mklabel();
1730 if (tok_see() != ';') {
1731 readestmt();
1732 ts_pop_de(NULL);
1733 j_fail = o_jz(0);
1734 has_cond = 1;
1736 tok_expect(';');
1737 j_pass = o_jmp(0);
1738 l_jump = o_mklabel();
1739 if (tok_see() != ')')
1740 readestmt();
1741 tok_expect(')');
1742 o_jmp(l_check);
1743 o_filljmp(j_pass);
1744 readstmt();
1745 o_jmp(l_jump);
1746 if (has_cond)
1747 o_filljmp(j_fail);
1748 break_fill(o_mklabel(), break_beg);
1749 continue_fill(l_jump, continue_beg);
1750 return;
1752 if (!tok_jmp(TOK_SWITCH)) {
1753 readswitch();
1754 return;
1756 if (!tok_jmp(TOK_RETURN)) {
1757 int ret = tok_see() != ';';
1758 if (ret) {
1759 readexpr();
1760 ts_pop_de(NULL);
1762 tok_expect(';');
1763 o_ret(ret);
1764 return;
1766 if (!tok_jmp(TOK_BREAK)) {
1767 tok_expect(';');
1768 breaks[nbreaks++] = o_jmp(0);
1769 return;
1771 if (!tok_jmp(TOK_CONTINUE)) {
1772 tok_expect(';');
1773 continues[ncontinues++] = o_jmp(0);
1774 return;
1776 if (!tok_jmp(TOK_GOTO)) {
1777 tok_expect(TOK_NAME);
1778 goto_add(tok_id());
1779 tok_expect(';');
1780 return;
1782 readestmt();
1783 /* labels */
1784 if (!tok_jmp(':')) {
1785 label_add(tok_id());
1786 return;
1788 tok_expect(';');
1791 static void readdecl(void)
1793 if (!tok_jmp(TOK_TYPEDEF)) {
1794 readdefs(typedefdef, NULL);
1795 tok_expect(';');
1796 return;
1798 readdefs(globaldef, NULL);
1799 if (tok_see() == '{') {
1800 readstmt();
1801 goto_fill();
1802 o_func_end();
1803 func_name[0] = '\0';
1804 nlocals = 0;
1805 ngotos = 0;
1806 nlabels = 0;
1807 return;
1809 tok_expect(';');
1812 static void parse(void)
1814 while (tok_see() != TOK_EOF)
1815 readdecl();
1818 int main(int argc, char *argv[])
1820 char obj[128];
1821 int ofd;
1822 int i = 1;
1823 while (i < argc && argv[i][0] == '-') {
1824 if (argv[i][1] == 'I')
1825 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1826 if (argv[i][1] == 'D') {
1827 char *name = argv[i] + 2;
1828 char *def = "";
1829 char *eq = strchr(name, '=');
1830 if (eq) {
1831 *eq = '\0';
1832 def = eq + 1;
1834 cpp_define(name, def);
1836 i++;
1838 if (i == argc)
1839 die("neatcc: no file given\n");
1840 if (cpp_init(argv[i]))
1841 die("neatcc: cannot open input file\n");
1842 parse();
1843 strcpy(obj, argv[i]);
1844 obj[strlen(obj) - 1] = 'o';
1845 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1846 o_write(ofd);
1847 close(ofd);
1848 return 0;